struct constraint* constraint;
}
+%term ALIASES
%term COPY
%term CORRUPTED
%term COST
%token <string> ID
%token <string> QFRAGMENT
+%type <stringlist> aliases;
%type <constraint> constraint
%type <constraint> constraints
%type <expr> predicate
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 ';'
p->name = id;
p->realname = realname;
p->number = number++;
+ array_append(&p->aliases, p);
smap_put(®isters, id, p);
return p;
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(®isters, f->data);
+ if (!r)
+ yyerror("register '%s' is not defined here", f->data);
+
+ array_appendu(®->aliases, r);
+ array_appendu(&r->aliases, reg);
+
+ f = f->next;
+ }
+}
+
struct regattr* getregattr(const char* id)
{
struct regattr* p = smap_get(®isterattrs, id);
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++)
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");
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
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