Add parsing support for register aliases.
authorDavid Given <dg@cowlark.com>
Thu, 20 Oct 2016 19:47:28 +0000 (21:47 +0200)
committerDavid Given <dg@cowlark.com>
Thu, 20 Oct 2016 19:47:28 +0000 (21:47 +0200)
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/mcgg.h
util/mcgg/scan.l

index 067ad3d..e6b1c2f 100644 (file)
@@ -25,6 +25,7 @@ extern int yylex(void);
     struct constraint* constraint;
 }
 
+%term ALIASES
 %term COPY
 %term CORRUPTED
 %term COST
@@ -43,6 +44,7 @@ extern int yylex(void);
 %token <string>     ID
 %token <string>     QFRAGMENT
 
+%type  <stringlist> aliases;
 %type  <constraint> constraint
 %type  <constraint> constraints
 %type  <expr>       predicate
@@ -72,10 +74,16 @@ registers
 
 register
     : ID QFRAGMENT                    { $$ = makereg($1, $2); }
+    | register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); }
     | register ID                     { $$ = $1; addregattr($1, $2, false); }
     | register ID '!'                 { $$ = $1; addregattr($1, $2, true); }
     ;
 
+aliases
+    : ID                              { $$ = calloc(1, sizeof(*$$)); stringlist_add($$, $1); }
+    | aliases ',' ID                  { $$ = $1; stringlist_add($$, $3); }
+    ;
+
 declarations
     : /* nothing */
     | declarations declaration ';'
index 39cdf97..cf7950b 100644 (file)
@@ -279,6 +279,7 @@ struct reg* makereg(const char* id, const char* realname)
        p->name = id;
        p->realname = realname;
        p->number = number++;
+       array_append(&p->aliases, p);
        smap_put(&registers, id, p);
 
        return p;
@@ -311,6 +312,34 @@ void addregattr(struct reg* reg, const char* id, bool exact)
                reg->type |= 1<<(p->number);
 }
 
+void addregalias(struct reg* r1, struct reg* r2)
+{
+       if (!array_appendu(&r1->aliases, r2))
+       {
+               int i;
+
+               for (i=0; i<r1->aliases.count; i++)
+                       addregalias(r1->aliases.item[i], r2);
+       }
+}
+
+void addregaliases(struct reg* reg, struct stringlist* aliases)
+{
+       struct stringfragment* f = aliases->first;
+
+       while (f)
+       {
+               struct reg* r = smap_get(&registers, f->data);
+               if (!r)
+                       yyerror("register '%s' is not defined here", f->data);
+
+               array_appendu(&reg->aliases, r);
+               array_appendu(&r->aliases, reg);
+
+               f = f->next;
+       }
+}
+
 struct regattr* getregattr(const char* id)
 {
        struct regattr* p = smap_get(&registerattrs, id);
@@ -588,7 +617,17 @@ static void emitregisterattrs(void)
 
 static void emitregisters(void)
 {
-       int i;
+       int i, j;
+
+       for (i=0; i<registers.count; i++)
+       {
+               struct reg* r = registers.item[i].right;
+
+               print("const struct %Pregister_data* %Pregister_aliases_%d_%s[] = {\n%1", i, r->name);
+               for (j=0; j<r->aliases.count; j++)
+                       print("&%Pregister_data[%d], ", r->aliases.item[j]->number);
+               print("NULL\n};\n");
+       }
 
        print("const struct %Pregister_data %Pregister_data[] = {\n");
        for (i=0; i<registers.count; i++)
@@ -596,8 +635,8 @@ static void emitregisters(void)
                struct reg* r = registers.item[i].right;
                assert(r->number == i);
 
-               print("%1{ \"%s\", \"%s\", 0x%x, 0x%x },\n",
-                       r->name, r->realname, r->type, r->attrs);
+               print("%1{ \"%s\", \"%s\", 0x%x, 0x%x, %Pregister_aliases_%d_%s },\n",
+                       r->name, r->realname, r->type, r->attrs, i, r->name);
        }
        print("%1{ NULL }\n");
        print("};\n\n");
index d12985e..f50e4c9 100644 (file)
@@ -58,11 +58,12 @@ struct terminfo
 
 struct reg
 {
-       const char* name;      /* friendly register name */
-       const char* realname;  /* name used in assembly output */
-       int number;            /* identifying number */
-       uint32_t attrs;        /* bitfield of register attributes */
-       uint32_t type;         /* register type */
+       const char* name;          /* friendly register name */
+       const char* realname;      /* name used in assembly output */
+       int number;                /* identifying number */
+       uint32_t attrs;            /* bitfield of register attributes */
+       uint32_t type;             /* register type */
+       ARRAYOF(struct reg) aliases; /* registers that this one aliases */
 };
 
 struct regattr
@@ -73,6 +74,7 @@ struct regattr
 
 extern struct reg* makereg(const char* name, const char* realname);
 extern void addregattr(struct reg* reg, const char* regattr, bool exact);
+extern void addregaliases(struct reg* reg, struct stringlist* aliases);
 extern struct regattr* getregattr(const char* name);
 
 struct term
index 2631e00..211aaf1 100644 (file)
@@ -67,6 +67,7 @@ struct burm_register_data
     const char* realname;
     uint32_t type;
     uint32_t attrs;
+    const struct burm_register_data** aliases;
 };
 
 extern const struct burm_register_data burm_register_data[];
index d26dfac..44a5824 100644 (file)
@@ -39,6 +39,7 @@ static int braces = 0;
 "DECLARATIONS"              return DECLARATIONS;
 "PATTERNS"                  return PATTERNS;
 "REGISTERS"                 return REGISTERS;
+"aliases"                   return ALIASES;
 "corrupted"                 return CORRUPTED;
 "cost"                      return COST;
 "emit"                      return EMIT;