Come up with a syntax for register constraints.
authorDavid Given <dg@cowlark.com>
Sun, 2 Oct 2016 19:51:25 +0000 (21:51 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 2 Oct 2016 19:51:25 +0000 (21:51 +0200)
mach/proto/mcg/table
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/scan.l

index d523cfb..4292dd8 100644 (file)
@@ -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;
 
index e65a625..9927d15 100644 (file)
@@ -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 <n>          INT
 %token <string>     ID
 %token <string>     QFRAGMENT
 
 %type  <nonterm>    allocates
+%type  <constraint> constraint
+%type  <constraint> constraints
 %type  <nonterm>    declaration
 %type  <reg>        register
-%type  <rule>       emit
+%type  <rule>       pattern_constraints
+%type  <rule>       pattern_emit
 %type  <rule>       pattern
-%type  <stringlist> cfragments
 %type  <stringlist> qfragments
 %type  <terminfo>   terminfo
 %type  <tree>       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; }
     ;
index 074198d..2fb6e2c 100644 (file)
@@ -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)
index 919f447..24700e5 100644 (file)
@@ -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);
index 30280c4..2d04f52 100644 (file)
@@ -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                ;