From 7214d1201f46119a5df4189f8c2757408b1d86ef Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 18 Dec 2016 20:21:22 +0100 Subject: [PATCH] Emit more detailed register class information. --- util/mcgg/iburg.c | 2 +- util/mcgg/mcgg.h | 10 +++- util/mcgg/registers.c | 122 ++++++++++++++++++++++++++++++------------ util/mcgg/registers.h | 2 + 4 files changed, 99 insertions(+), 37 deletions(-) diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 8b5e2cccc..a95065dd9 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -160,8 +160,8 @@ int main(int argc, char* argv[]) yyparse(); analyse_registers(); - emitregisterattrs(); emitregisters(); + emitregisterattrs(); emitdefs(nts, ntnumber); emitstruct(nts, ntnumber); emitnts(rules, nrules); diff --git a/util/mcgg/mcgg.h b/util/mcgg/mcgg.h index e4baa7cf7..e9ed5b45d 100644 --- a/util/mcgg/mcgg.h +++ b/util/mcgg/mcgg.h @@ -58,12 +58,18 @@ struct burm_register_data const char* id; uint32_t attrs; const char** names; - const struct burm_register_data** aliases; + burm_register_bitmap_t bitmap; +}; + +struct burm_regclass_data +{ + const char* name; + const struct burm_register_data** registers; burm_register_bitmap_t bitmap; }; extern const struct burm_register_data burm_register_data[]; -extern const char* burm_register_class_names[]; +extern const struct burm_regclass_data burm_regclass_data[]; #endif diff --git a/util/mcgg/registers.c b/util/mcgg/registers.c index f8ca3d116..e998cd8ed 100644 --- a/util/mcgg/registers.c +++ b/util/mcgg/registers.c @@ -72,6 +72,7 @@ void addregattr(struct reg* reg, const char* id) p = makeregattr(id); reg->attrs |= 1<<(p->number); + set_add(®->classes, p); } void addregalias(struct reg* r1, struct reg* r2) @@ -118,6 +119,8 @@ void analyse_registers(void) struct hashtable_iterator hit = {}; int i, j; + /* Collect registers in declaration order. */ + while (hashtable_next(®isters, &hit)) { struct reg* r = hit.value; @@ -130,6 +133,8 @@ void analyse_registers(void) real_register_count = 0; fake_register_count = 0; + /* Count which registers are real vs fake. */ + for (i=0; ibitmap = bitmap_alloc(real_register_count); + } + } + + { + struct hashtable_iterator hit = {}; + while (hashtable_next(®isters, &hit)) + { + struct reg* r = hit.value; + struct set_iterator sit = {}; + while (set_next(&r->classes, &sit)) + { + struct regattr* rc = sit.item; + bitmap_or(rc->bitmap, real_register_count, r->bitmap); + } + } + } + printh("typedef unsigned int %Pregister_bitmap_t[%d];\n", WORDS_FOR_BITMAP_SIZE(real_register_count)); } void emitregisterattrs(void) { - int i; + int i, j; struct regattr* regattrs[registerattrs.size]; - struct hashtable_iterator hit = {}; + struct reg* regs[registers.size]; + + { + struct hashtable_iterator hit = {}; + while (hashtable_next(®isters, &hit)) + { + struct reg* r = hit.value; + assert((r->number >= 0) && (r->number < registers.size)); + regs[r->number] = r; + } + } + + { + struct hashtable_iterator hit = {}; + while (hashtable_next(®isterattrs, &hit)) + { + struct regattr* rc = hit.value; + assert((rc->number >= 0) && (rc->number < registerattrs.size)); + regattrs[rc->number] = rc; + } + } - while (hashtable_next(®isterattrs, &hit)) + for (i=0; inumber >= 0) && (rc->number < registerattrs.size)); - regattrs[rc->number] = rc; + struct regattr* rc = regattrs[i]; + print("static const struct %Pregister_data* %Pregisters_in_class_%s[] = {\n", + rc->name); + + for (j=0; jclasses, rc)) + print("&%Pregister_data[%d], ", r->number); + } + + print("NULL };\n"); } - print("const char* %Pregister_class_names[] = {\n"); + print("\nconst struct %Pregclass_data %Pregclass_data[] = {\n"); for (i=0; inumber == i); - print("%1\"%s\",\n", rc->name); + print("%1{ \"%s\", %Pregisters_in_class_%s, { ", rc->name, rc->name); + for (j=0; jbitmap[j]); + } + print("}},\n"); printh("#define %P%s_ATTR (1U<<%d)\n", rc->name, rc->number); } print("};\n\n"); @@ -192,30 +258,22 @@ void emitregisters(void) { int i, j; struct reg* regs[registers.size]; - struct hashtable_iterator hit = {}; - while (hashtable_next(®isters, &hit)) { - struct reg* r = hit.value; - assert((r->number >= 0) && (r->number < registers.size)); - regs[r->number] = r; - } - - for (i=0; iname); - for (j=0; jaliases.count; j++) - print("&%Pregister_data[%d], ", r->aliases.item[j]->number); - print("NULL\n};\n"); + struct hashtable_iterator hit = {}; + while (hashtable_next(®isters, &hit)) + { + struct reg* r = hit.value; + assert((r->number >= 0) && (r->number < registers.size)); + regs[r->number] = r; + } } for (i=0; iname); + print("static const char* %Pregister_names_%s[] = { ", r->name); if (r->names) { struct stringfragment* f = r->names->first; @@ -227,28 +285,24 @@ void emitregisters(void) } else print("\"%s\", ", r->name); - print("NULL\n};\n"); + print("NULL };\n"); } - print("const struct %Pregister_data %Pregister_data[] = {\n"); + print("\nconst struct %Pregister_data %Pregister_data[] = {\n"); for (i=0; inumber == i); - - print("%1{\n%2\"%s\", 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s,\n", - r->name, r->attrs, i, r->name, i, r->name); - print("%2{ "); + print("%1{ \"%s\", 0x%x, %Pregister_names_%s, ", + r->name, r->attrs, r->name, r->name); + print("{ "); for (j=0; jbitmap[j]); } - print("},\n"); - print("%1},\n"); + print("}},\n"); } - - print("%1{ NULL }\n"); print("};\n\n"); } diff --git a/util/mcgg/registers.h b/util/mcgg/registers.h index 828ab5a2a..20b74f754 100644 --- a/util/mcgg/registers.h +++ b/util/mcgg/registers.h @@ -2,12 +2,14 @@ #define REGISTERS_H #include "array.h" +#include "set.h" struct reg { const char* name; /* friendly register name */ int number; /* identifying number */ uint32_t attrs; /* bitfield of register attributes */ + struct set classes; /* register classes this register belongs to */ struct stringlist* names; /* register names */ unsigned int* bitmap; /* hardware register bitmap */ ARRAYOF(struct reg) aliases; /* registers that this one aliases */ -- 2.34.1