diff --git a/mach/proto/mcg/table b/mach/proto/mcg/table index d523cfb09..4292dd8e0 100644 --- a/mach/proto/mcg/table +++ b/mach/proto/mcg/table @@ -29,6 +29,9 @@ REGISTERS DECLARATIONS + reg; + cc; + address fragment; aluparam fragment; @@ -37,88 +40,75 @@ PATTERNS /* Special */ - int; - float; - any; + reg; PAIR(BLOCK4, BLOCK4); /* Miscellaneous special things */ - PUSH4(in:int) + PUSH4(in:reg) emit "push %in" cost 4; - int = POP4 - emit "pop %int" + reg = POP4 + emit "pop %reg" cost 4; RET emit "ret" cost 4; - SETRET4(in:ret) - emit "mov r0, %in" + SETRET4(in:reg) + with ret reg cost 4; STACKADJUST4(delta:aluparam) emit "add sp, sp, %delta" cost 4; - int = in:REG4 - prefers int(in) + reg = in:REG4 + with (reg == in) cost 1; - int = NOP4(in:int) - emit "mov %int, %in" + reg = NOP4(in:reg) + with (reg == in) cost 1; - any = PHI4 - cost 0; - - float = in:REG4 - prefers float(in) - cost 1; - - ret = in:any emit "mov %ret, %in" cost 1; - any = in:int emit "mov %any, %in" cost 1; - int = in:any emit "mov %int, %in" cost 1; - any = in:float emit "mov %any, %in" cost 1; - float = in:any emit "mov %float, %in" cost 1; - /* Memory operations */ - STORE4(addr:address, value:int) + STORE4(addr:address, value:reg) + with int value emit "str %value, %addr" cost 4; - STORE1(addr:address, value:int) + STORE1(addr:address, value:reg) + with int value emit "strb %value, %addr" cost 4; - int = LOAD4(addr:address) - emit "ldr %int, %addr" + reg = LOAD4(addr:address) + emit "ldr %reg, %addr" cost 4; - int = LOAD1(addr:address) - emit "ldrb %int, %addr" + reg = LOAD1(addr:address) + emit "ldrb %reg, %addr" cost 4; - int = CIU14(LOAD1(addr:address)) - emit "ldrb %int, %addr" + reg = CIU14(LOAD1(addr:address)) + emit "ldrb %reg, %addr" cost 4; - int = CII14(CIU41(CIU14(LOAD1(addr:address)))) - emit "ldrsb %int, %addr" + reg = CII14(CIU41(CIU14(LOAD1(addr:address)))) + emit "ldrsb %reg, %addr" cost 4; /* Locals */ - int = in:LOCAL4 - emit "add %int, fp, #$in" + reg = in:LOCAL4 + emit "add %reg, fp, #$in" cost 4; address = in:LOCAL4 @@ -127,13 +117,16 @@ PATTERNS /* Memory addressing modes */ - address = ADD4(addr:int, offset:CONST4) + address = ADD4(addr:reg, offset:CONST4) + with int addr emit "[%addr, #$offset]"; - address = ADD4(addr1:int, addr2:int) + address = ADD4(addr1:reg, addr2:reg) + with int addr1, int addr2 emit "[%addr1, %addr2]"; - address = addr:int + address = addr:reg + with int addr emit "[%addr]"; @@ -166,80 +159,80 @@ PATTERNS /* Comparisons */ - cc = COMPARES4(left:int, right:aluparam) + cc = COMPARES4(left:reg, right:aluparam) emit "cmp %left, %right" cost 4; - cc = COMPARES4(COMPARES4(left:int, right:aluparam), CONST4) + cc = COMPARES4(COMPARES4(left:reg, right:aluparam), CONST4) emit "cmp %left, %right" cost 4; - int = cc - emit "mov %int, #0" - emit "movlt %int, #-1" - emit "movgt %int, #1" + reg = cc + emit "mov %reg, #0" + emit "movlt %reg, #-1" + emit "movgt %reg, #1" cost 12; /* Conversions */ - int = CII14(CIU41(value:int)) - emit "sxtb %int, %value" + reg = CII14(CIU41(value:reg)) + emit "sxtb %reg, %value" cost 4; - int = CIU41(in:int) - emit "and %int, %in, #0xff" + reg = CIU41(in:reg) + emit "and %reg, %in, #0xff" cost 4; /* ALU operations */ - int = ADD4(left:int, right:aluparam) - emit "add %int, %left, %right" + reg = ADD4(left:reg, right:aluparam) + emit "add %reg, %left, %right" cost 4; - int = ADD4(left:aluparam, right:int) - emit "add %int, %right, %left" + reg = ADD4(left:aluparam, right:reg) + emit "add %reg, %right, %left" cost 4; - int = MOD4(left:int, right:int) - emit "udiv %int, %left, %right" - emit "mls %int, %int, %right, %left" + reg = MOD4(left:reg, right:reg) + emit "udiv %reg, %left, %right" + emit "mls %reg, %reg, %right, %left" cost 8; - int = DIV4(left:int, right:aluparam) - emit "div %int, %left, %right" + reg = DIV4(left:reg, right:aluparam) + emit "div %reg, %left, %right" cost 4; aluparam = value:CONST4 emit "#$value"; - aluparam = value:int + aluparam = value:reg emit "%value"; - int = value:aluparam - emit "mov %int, %value" + reg = value:aluparam + emit "mov %reg, %value" cost 4; - int = value:LABEL4 - emit "adr %int, $value" + reg = value:LABEL4 + emit "adr %reg, $value" cost 4; - int = value:BLOCK4 - emit "adr %int, $value" + reg = value:BLOCK4 + emit "adr %reg, $value" cost 4; - int = value:CONST4 - emit "ldr %int, address-containing-$value" + reg = value:CONST4 + emit "ldr %reg, address-containing-$value" cost 8; - float = value:CONSTF4 - emit "vldr %float, address-containing-$value" + reg = value:CONSTF4 + emit "vldr %reg, address-containing-$value" cost 8; /* FPU operations */ - float = ADDF4(left:float, right:float) - emit "fadds %float, %left, %right" + reg = ADDF4(left:reg, right:reg) + emit "fadds %reg, %left, %right" cost 4; diff --git a/util/mcgg/gram.y b/util/mcgg/gram.y index e65a6256b..9927d1598 100644 --- a/util/mcgg/gram.y +++ b/util/mcgg/gram.y @@ -24,28 +24,34 @@ static int nextern = 1; struct stringlist* stringlist; struct terminfo terminfo; struct expr* expr; + struct constraint* constraint; } %term ALLOCATES %term COST %term DECLARATIONS %term EMIT +%term EQUALS %term FRAGMENT +%term NOTEQUALS %term PATTERNS -%term REGISTERS %term PREFERS -%term REQUIRES +%term REGISTERS +%term WHEN +%term WITH %token INT %token ID %token QFRAGMENT %type allocates +%type constraint +%type constraints %type declaration %type register -%type emit +%type pattern_constraints +%type pattern_emit %type pattern -%type cfragments %type qfragments %type terminfo %type rhs @@ -102,9 +108,10 @@ pattern : ID '=' rhs { nonterm($1, false); $$ = rule($1, $3, nextern++); } | rhs { $$ = rule("stmt", $1, nextern++); } | pattern PREFERS predicate { $$ = $1; array_append(&$$->prefers, $3); } - | pattern REQUIRES predicate { $$ = $1; array_append(&$$->requires, $3); } - | emit { $$ = $1; } + | pattern WHEN predicate { $$ = $1; array_append(&$$->requires, $3); } | pattern COST INT { $$ = $1; $$->cost = $3; } + | pattern_constraints { $$ = $1; } + | pattern_emit { $$ = $1; } ; rhs @@ -115,12 +122,10 @@ rhs terminfo : ID { $$.name = $1; } - | ID '.' ID { $$.name = $1; $$.regattr = $3; } | ID ':' ID { $$.label = $1; $$.name = $3; } - | ID ':' ID '.' ID { $$.label = $1; $$.name = $3; $$.regattr = $5; } ; -emit +pattern_emit : pattern EMIT qfragments { $$ = $1; if (!$$->lhs->is_fragment) @@ -129,6 +134,33 @@ emit } ; +pattern_constraints + : pattern WITH constraints { + struct constraint* c = $3; + $$ = $1; + while (c) + { + array_append(&$$->constraints, c); + c = c->next; + } + } + ; + +constraints + : constraint { $$ = $1; } + | constraints ',' constraint { $$ = $3; $$->next = $1; } + ; + +constraint + : '(' constraint ')' { $$ = $2; } + | ID ID { $$ = calloc(1, sizeof(*$$)); + $$->type = CONSTRAINT_ATTR; $$->left = $1; $$->right = $2; } + | ID EQUALS ID { $$ = calloc(1, sizeof(*$$)); + $$->type = CONSTRAINT_EQUALS; $$->left = $1; $$->right = $3; } + | ID NOTEQUALS ID { $$ = calloc(1, sizeof(*$$)); + $$->type = CONSTRAINT_NOTEQUALS; $$->left = $1; $$->right = $3; } + ; + qfragments : /* nothing */ { $$ = calloc(1, sizeof *$$); } | qfragments QFRAGMENT { $$ = $1; stringlist_add($$, $2); } @@ -139,7 +171,7 @@ predicate ; predicate_args - : /* nothing */ + : /* nothing */ { $$ = NULL; } | ID { $$ = calloc(1, sizeof *$$); $$->name = $1; } | ID ',' predicate_args { $$ = calloc(1, sizeof *$$); $$->name = $1; $$->next = $3; } ; diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 074198d0c..2fb6e2cab 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -262,7 +262,6 @@ void addregclass(struct reg* reg, const char* id) } reg->classes |= 1<<(p->number); - nonterm(id, true); } struct regclass* getregclass(const char* id) diff --git a/util/mcgg/iburg.h b/util/mcgg/iburg.h index 919f4471d..24700e5e4 100644 --- a/util/mcgg/iburg.h +++ b/util/mcgg/iburg.h @@ -16,6 +16,21 @@ typedef enum typedef struct rule* Rule; typedef struct term* Term; +enum +{ + CONSTRAINT_ATTR, + CONSTRAINT_EQUALS, + CONSTRAINT_NOTEQUALS +}; + +struct constraint +{ + int type; + const char* left; + const char* right; + struct constraint* next; +}; + struct expr { const char* name; @@ -26,7 +41,6 @@ struct terminfo { const char* name; const char* label; - const char* regattr; }; struct reg @@ -97,8 +111,9 @@ struct rule Rule chain; /* next chain rule with same rhs */ Rule decode; /* next rule with same lhs */ Rule kids; /* next rule with same burm_kids pattern */ - ARRAYOF(struct predicate) prefers; /* C predicates */ - ARRAYOF(struct predicate) requires; /* C predicates */ + ARRAYOF(struct expr) prefers; /* C predicates */ + ARRAYOF(struct expr) requires; /* C predicates */ + ARRAYOF(struct constraint) constraints; /* register constraints */ struct stringlist code; /* compiler output code strings */ }; extern Rule rule(char* id, Tree pattern, int ern); diff --git a/util/mcgg/scan.l b/util/mcgg/scan.l index 30280c492..2d04f52c0 100644 --- a/util/mcgg/scan.l +++ b/util/mcgg/scan.l @@ -43,7 +43,10 @@ static int braces = 0; "emit" return EMIT; "fragment" return FRAGMENT; "prefers" return PREFERS; -"requires" return REQUIRES; +"when" return WHEN; +"with" return WITH; +"==" return EQUALS; +"!=" return NOTEQUALS; "//"[^\n]*\n ;