Add parsing support for register aliases.
This commit is contained in:
parent
e4fec71f9c
commit
d6984d60ac
|
@ -25,6 +25,7 @@ extern int yylex(void);
|
||||||
struct constraint* constraint;
|
struct constraint* constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%term ALIASES
|
||||||
%term COPY
|
%term COPY
|
||||||
%term CORRUPTED
|
%term CORRUPTED
|
||||||
%term COST
|
%term COST
|
||||||
|
@ -43,6 +44,7 @@ extern int yylex(void);
|
||||||
%token <string> ID
|
%token <string> ID
|
||||||
%token <string> QFRAGMENT
|
%token <string> QFRAGMENT
|
||||||
|
|
||||||
|
%type <stringlist> aliases;
|
||||||
%type <constraint> constraint
|
%type <constraint> constraint
|
||||||
%type <constraint> constraints
|
%type <constraint> constraints
|
||||||
%type <expr> predicate
|
%type <expr> predicate
|
||||||
|
@ -72,10 +74,16 @@ registers
|
||||||
|
|
||||||
register
|
register
|
||||||
: ID QFRAGMENT { $$ = makereg($1, $2); }
|
: ID QFRAGMENT { $$ = makereg($1, $2); }
|
||||||
|
| register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); }
|
||||||
| register ID { $$ = $1; addregattr($1, $2, false); }
|
| register ID { $$ = $1; addregattr($1, $2, false); }
|
||||||
| register ID '!' { $$ = $1; addregattr($1, $2, true); }
|
| register ID '!' { $$ = $1; addregattr($1, $2, true); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
aliases
|
||||||
|
: ID { $$ = calloc(1, sizeof(*$$)); stringlist_add($$, $1); }
|
||||||
|
| aliases ',' ID { $$ = $1; stringlist_add($$, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
declarations
|
declarations
|
||||||
: /* nothing */
|
: /* nothing */
|
||||||
| declarations declaration ';'
|
| declarations declaration ';'
|
||||||
|
|
|
@ -279,6 +279,7 @@ struct reg* makereg(const char* id, const char* realname)
|
||||||
p->name = id;
|
p->name = id;
|
||||||
p->realname = realname;
|
p->realname = realname;
|
||||||
p->number = number++;
|
p->number = number++;
|
||||||
|
array_append(&p->aliases, p);
|
||||||
smap_put(®isters, id, p);
|
smap_put(®isters, id, p);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
@ -311,6 +312,34 @@ void addregattr(struct reg* reg, const char* id, bool exact)
|
||||||
reg->type |= 1<<(p->number);
|
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* getregattr(const char* id)
|
||||||
{
|
{
|
||||||
struct regattr* p = smap_get(®isterattrs, id);
|
struct regattr* p = smap_get(®isterattrs, id);
|
||||||
|
@ -588,7 +617,17 @@ static void emitregisterattrs(void)
|
||||||
|
|
||||||
static void emitregisters(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");
|
print("const struct %Pregister_data %Pregister_data[] = {\n");
|
||||||
for (i=0; i<registers.count; i++)
|
for (i=0; i<registers.count; i++)
|
||||||
|
@ -596,8 +635,8 @@ static void emitregisters(void)
|
||||||
struct reg* r = registers.item[i].right;
|
struct reg* r = registers.item[i].right;
|
||||||
assert(r->number == i);
|
assert(r->number == i);
|
||||||
|
|
||||||
print("%1{ \"%s\", \"%s\", 0x%x, 0x%x },\n",
|
print("%1{ \"%s\", \"%s\", 0x%x, 0x%x, %Pregister_aliases_%d_%s },\n",
|
||||||
r->name, r->realname, r->type, r->attrs);
|
r->name, r->realname, r->type, r->attrs, i, r->name);
|
||||||
}
|
}
|
||||||
print("%1{ NULL }\n");
|
print("%1{ NULL }\n");
|
||||||
print("};\n\n");
|
print("};\n\n");
|
||||||
|
|
|
@ -58,11 +58,12 @@ struct terminfo
|
||||||
|
|
||||||
struct reg
|
struct reg
|
||||||
{
|
{
|
||||||
const char* name; /* friendly register name */
|
const char* name; /* friendly register name */
|
||||||
const char* realname; /* name used in assembly output */
|
const char* realname; /* name used in assembly output */
|
||||||
int number; /* identifying number */
|
int number; /* identifying number */
|
||||||
uint32_t attrs; /* bitfield of register attributes */
|
uint32_t attrs; /* bitfield of register attributes */
|
||||||
uint32_t type; /* register type */
|
uint32_t type; /* register type */
|
||||||
|
ARRAYOF(struct reg) aliases; /* registers that this one aliases */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct regattr
|
struct regattr
|
||||||
|
@ -73,6 +74,7 @@ struct regattr
|
||||||
|
|
||||||
extern struct reg* makereg(const char* name, const char* realname);
|
extern struct reg* makereg(const char* name, const char* realname);
|
||||||
extern void addregattr(struct reg* reg, const char* regattr, bool exact);
|
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);
|
extern struct regattr* getregattr(const char* name);
|
||||||
|
|
||||||
struct term
|
struct term
|
||||||
|
|
|
@ -67,6 +67,7 @@ struct burm_register_data
|
||||||
const char* realname;
|
const char* realname;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t attrs;
|
uint32_t attrs;
|
||||||
|
const struct burm_register_data** aliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct burm_register_data burm_register_data[];
|
extern const struct burm_register_data burm_register_data[];
|
||||||
|
|
|
@ -39,6 +39,7 @@ static int braces = 0;
|
||||||
"DECLARATIONS" return DECLARATIONS;
|
"DECLARATIONS" return DECLARATIONS;
|
||||||
"PATTERNS" return PATTERNS;
|
"PATTERNS" return PATTERNS;
|
||||||
"REGISTERS" return REGISTERS;
|
"REGISTERS" return REGISTERS;
|
||||||
|
"aliases" return ALIASES;
|
||||||
"corrupted" return CORRUPTED;
|
"corrupted" return CORRUPTED;
|
||||||
"cost" return COST;
|
"cost" return COST;
|
||||||
"emit" return EMIT;
|
"emit" return EMIT;
|
||||||
|
|
Loading…
Reference in a new issue