From d6984d60acf3a66c22ef547066dabbd3b2dd437b Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 20 Oct 2016 21:47:28 +0200 Subject: [PATCH] Add parsing support for register aliases. --- util/mcgg/gram.y | 8 ++++++++ util/mcgg/iburg.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- util/mcgg/iburg.h | 12 +++++++----- util/mcgg/mcgg.h | 1 + util/mcgg/scan.l | 1 + 5 files changed, 59 insertions(+), 8 deletions(-) diff --git a/util/mcgg/gram.y b/util/mcgg/gram.y index 067ad3d8d..e6b1c2fd0 100644 --- a/util/mcgg/gram.y +++ b/util/mcgg/gram.y @@ -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 ID %token QFRAGMENT +%type aliases; %type constraint %type constraints %type 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 ';' diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 39cdf9729..cf7950b26 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -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(®isters, 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; ialiases.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); @@ -588,7 +617,17 @@ static void emitregisterattrs(void) static void emitregisters(void) { - int i; + int i, j; + + for (i=0; iname); + for (j=0; jaliases.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; inumber == 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"); diff --git a/util/mcgg/iburg.h b/util/mcgg/iburg.h index d12985eb6..f50e4c9da 100644 --- a/util/mcgg/iburg.h +++ b/util/mcgg/iburg.h @@ -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 diff --git a/util/mcgg/mcgg.h b/util/mcgg/mcgg.h index 2631e0097..211aaf1cc 100644 --- a/util/mcgg/mcgg.h +++ b/util/mcgg/mcgg.h @@ -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[]; diff --git a/util/mcgg/scan.l b/util/mcgg/scan.l index d26dfac81..44a582456 100644 --- a/util/mcgg/scan.l +++ b/util/mcgg/scan.l @@ -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;