From 92502901a71b4f049731f7cd463fbcd3d7158bf2 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 5 Oct 2016 21:00:28 +0200 Subject: [PATCH] Better management of register data. Add struct hreg. --- mach/proto/mcg/mcg.h | 2 +- mach/proto/mcg/pass_splitcriticaledges.c | 1 - mach/proto/mcg/reg.c | 32 ++++++++++ mach/proto/mcg/reg.h | 26 ++++++++ mach/proto/mcg/table | 44 +++++++------- mach/proto/mcg/vreg.c | 10 --- mach/proto/mcg/vreg.h | 12 ---- util/mcgg/gram.y | 4 +- util/mcgg/iburg.c | 77 ++++++++++++++---------- util/mcgg/iburg.h | 10 +-- util/mcgg/mcgg.h | 10 ++- 11 files changed, 141 insertions(+), 87 deletions(-) create mode 100644 mach/proto/mcg/reg.c create mode 100644 mach/proto/mcg/reg.h delete mode 100644 mach/proto/mcg/vreg.c delete mode 100644 mach/proto/mcg/vreg.h diff --git a/mach/proto/mcg/mcg.h b/mach/proto/mcg/mcg.h index dc70028c9..07da36467 100644 --- a/mach/proto/mcg/mcg.h +++ b/mach/proto/mcg/mcg.h @@ -24,7 +24,7 @@ #include "ir.h" #include "mcgg.h" #include "hop.h" -#include "vreg.h" +#include "reg.h" #include "basicblock.h" #include "procedure.h" diff --git a/mach/proto/mcg/pass_splitcriticaledges.c b/mach/proto/mcg/pass_splitcriticaledges.c index a7fa63ee9..9237be750 100644 --- a/mach/proto/mcg/pass_splitcriticaledges.c +++ b/mach/proto/mcg/pass_splitcriticaledges.c @@ -88,4 +88,3 @@ void pass_split_critical_edges(struct procedure* proc) /* vim: set sw=4 ts=4 expandtab : */ - diff --git a/mach/proto/mcg/reg.c b/mach/proto/mcg/reg.c new file mode 100644 index 000000000..c4cf71058 --- /dev/null +++ b/mach/proto/mcg/reg.c @@ -0,0 +1,32 @@ +#include "mcg.h" + +static int vreg_count = 1; + +struct vreg* new_vreg(void) +{ + struct vreg* vreg = calloc(1, sizeof *vreg); + vreg->id = vreg_count++; + return vreg; +} + +struct hreg* new_hreg(struct burm_register_data* brd) +{ + struct hreg* hreg = calloc(1, sizeof *hreg); + hreg->name = brd->name; + hreg->attrs = brd->attrs; + hreg->is_stacked = false; + return hreg; +} + +struct hreg* new_stacked_hreg(int offset, uint32_t attrs) +{ + struct hreg* hreg = calloc(1, sizeof *hreg); + hreg->name = aprintf("stacked_%d", offset); + hreg->attrs = attrs; + hreg->is_stacked = true; + hreg->offset = offset; + return hreg; +} + +/* vim: set sw=4 ts=4 expandtab : */ + diff --git a/mach/proto/mcg/reg.h b/mach/proto/mcg/reg.h new file mode 100644 index 000000000..62bbb6900 --- /dev/null +++ b/mach/proto/mcg/reg.h @@ -0,0 +1,26 @@ +#ifndef REG_H +#define REG_H + +#define WITH_ATTR(a) (1<<(a)) + +struct hreg +{ + const char* name; + uint32_t attrs; + bool is_stacked; + int offset; +}; + +struct vreg +{ + int id; +}; + +extern struct vreg* new_vreg(void); + +extern struct hreg* new_hreg(struct burm_register_data* brd); +extern struct hreg* new_stacked_hreg(int offset, uint32_t attrs); + +#endif + +/* vim: set sw=4 ts=4 expandtab : */ diff --git a/mach/proto/mcg/table b/mach/proto/mcg/table index c333a6310..8ff3b2416 100644 --- a/mach/proto/mcg/table +++ b/mach/proto/mcg/table @@ -1,28 +1,28 @@ REGISTERS - r0 any int ret; - r1 any int; - r2 any int; - r3 any int; - r4 any int; - r5 any int; - r6 any int; - r7 any int; - r8 any int; - r9 any int; - r10 any int; - r11 any int; + r0 bytes4 int ret; + r1 bytes4 int; + r2 bytes4 int; + r3 bytes4 int; + r4 bytes4 int; + r5 bytes4 int; + r6 bytes4 int; + r7 bytes4 int; + r8 bytes4 int; + r9 bytes4 int; + r10 bytes4 int; + r11 bytes4 int; - s0 any float; - s1 any float; - s2 any float; - s3 any float; - s4 any float; - s5 any float; - s6 any float; - s7 any float; - s8 any float; - s9 any float; + s0 bytes4 float; + s1 bytes4 float; + s2 bytes4 float; + s3 bytes4 float; + s4 bytes4 float; + s5 bytes4 float; + s6 bytes4 float; + s7 bytes4 float; + s8 bytes4 float; + s9 bytes4 float; cc cc; diff --git a/mach/proto/mcg/vreg.c b/mach/proto/mcg/vreg.c deleted file mode 100644 index 636475de7..000000000 --- a/mach/proto/mcg/vreg.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "mcg.h" - -static int vreg_count = 1; - -struct vreg* new_vreg(void) -{ - struct vreg* vreg = calloc(1, sizeof *vreg); - vreg->id = vreg_count++; - return vreg; -} diff --git a/mach/proto/mcg/vreg.h b/mach/proto/mcg/vreg.h deleted file mode 100644 index ef92fd224..000000000 --- a/mach/proto/mcg/vreg.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef VREG_H -#define VREG_H - -struct vreg -{ - int id; -}; - -extern struct vreg* new_vreg(void); - -#endif - diff --git a/util/mcgg/gram.y b/util/mcgg/gram.y index 5dc23a8be..a7ba08d70 100644 --- a/util/mcgg/gram.y +++ b/util/mcgg/gram.y @@ -74,7 +74,7 @@ registers register : ID { $$ = makereg($1); } - | register ID { $$ = $1; addregclass($1, $2); } + | register ID { $$ = $1; addregattr($1, $2); } ; declarations @@ -95,7 +95,7 @@ allocates $$ = $1; if ($$->allocate) yyerror("pattern type is defined to already allocate a register"); - $$->allocate = getregclass($4); + $$->allocate = getregattr($4); } ; diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 3eb703bcf..b9ecd2cd2 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -29,11 +29,12 @@ static Rule rules; static int nrules; static SMAPOF(struct reg) registers; -static SMAPOF(struct regclass) registerclasses; +static SMAPOF(struct regattr) registerattrs; static void print(char* fmt, ...); static void ckreach(Nonterm p); static void registerterminals(void); +static struct regattr* makeregattr(const char* id); static void emitclosure(Nonterm nts); static void emitcost(Tree t, const char* v); static void emitcostcalc(Rule r); @@ -47,7 +48,7 @@ static void emitleaf(Term p, int ntnumber); static void emitnts(Rule rules, int nrules); static void emitpredicatedefinitions(Rule rules); static void emitrecord(char* pre, Rule r, int cost); -static void emitregisterclasses(); +static void emitregisterattrs(); static void emitregisters(); static void emitrule(Nonterm nts); static void emitstate(Term terms, Nonterm start, int ntnumber); @@ -125,6 +126,10 @@ int main(int argc, char* argv[]) registerterminals(); start = nonterm("stmt", true); + makeregattr("bytes1"); + makeregattr("bytes2"); + makeregattr("bytes4"); + makeregattr("bytes8"); yyin = infp; yyparse(); @@ -137,7 +142,7 @@ int main(int argc, char* argv[]) yyerror("can't reach non-terminal `%s'\n", p->name); #endif - emitregisterclasses(); + emitregisterattrs(); emitregisters(); emitdefs(nts, ntnumber); emitstruct(nts, ntnumber); @@ -194,7 +199,7 @@ struct entry struct term t; struct nonterm nt; struct reg r; - struct regclass rc; + struct regattr rc; } sym; struct entry* link; } * table[211]; @@ -236,7 +241,7 @@ static void* install(const char* name) struct reg* makereg(const char* id) { struct reg* p = smap_get(®isters, id); - static int number = 1; + static int number = 0; if (p) yyerror("redefinition of '%s'", id); @@ -248,25 +253,34 @@ struct reg* makereg(const char* id) return p; } -void addregclass(struct reg* reg, const char* id) +struct regattr* makeregattr(const char* id) { - struct regclass* p = smap_get(®isterclasses, id); - static int number = 1; + struct regattr* p = smap_get(®isterattrs, id); + static int number = 0; - if (!p) - { - p = calloc(1, sizeof(*p)); - p->name = id; - p->number = number++; - smap_put(®isterclasses, id, p); - } + if (p) + yyerror("redefinition of '%s'", id); + p = calloc(1, sizeof(*p)); + p->name = id; + p->number = number++; + smap_put(®isterattrs, id, p); - reg->classes |= 1<<(p->number); + return p; } -struct regclass* getregclass(const char* id) +void addregattr(struct reg* reg, const char* id) { - struct regclass* p = smap_get(®isterclasses, id); + struct regattr* p = smap_get(®isterattrs, id); + + if (!p) + p = makeregattr(id); + + reg->attrs |= 1<<(p->number); +} + +struct regattr* getregattr(const char* id) +{ + struct regattr* p = smap_get(®isterattrs, id); if (!p) yyerror("'%s' is not the name of a register class", id); return p; @@ -318,9 +332,6 @@ Term term(const char* id, int esn) p->name, p->esn); p->link = *q; *q = p; - - if (esn != -1) - print("enum { %s = %d };\n", id, esn); return p; } @@ -415,10 +426,6 @@ static void print(char* fmt, ...) fprintf(outfp, "%x", va_arg(ap, uint32_t)); break; - case 'X': - fprintf(outfp, "0x%" PRIx64 "ULL", va_arg(ap, uint64_t)); - break; - case 's': fputs(va_arg(ap, char*), outfp); break; @@ -499,16 +506,15 @@ static void ckreach(Nonterm p) reach(r->pattern); } -static void emitregisterclasses(void) +static void emitregisterattrs(void) { int i; print("const char* %Pregister_class_names[] = {\n"); - print("%1NULL,\n"); /* register class id 0 is invalid */ - for (i=0; inumber == (i+1)); + struct regattr* rc = registerattrs.item[i].right; + assert(rc->number == i); print("%1\"%s\",\n", rc->name); } @@ -520,14 +526,14 @@ static void emitregisters(void) int i; print("const struct %Pregister_data %Pregister_data[] = {\n"); - print("%1{ 0 },\n"); /* register id 0 is invalid */ for (i=0; inumber == (i+1)); + assert(r->number == i); - print("%1{ \"%s\", %X },\n", r->name, r->classes); + print("%1{ \"%s\", 0x%x },\n", r->name, r->attrs); } + print("%1{ NULL }\n"); print("};\n\n"); } @@ -1168,6 +1174,11 @@ static void emitterms(Term terms) Term p; int k; + print("enum {\n"); + for (k = 0, p = terms; p; p = p->link) + print("%1%S = %d,\n", p, p->esn); + print("};\n\n"); + print("static const char %Parity[] = {\n"); for (k = 0, p = terms; p; p = p->link) { diff --git a/util/mcgg/iburg.h b/util/mcgg/iburg.h index 24700e5e4..60e51d7b4 100644 --- a/util/mcgg/iburg.h +++ b/util/mcgg/iburg.h @@ -47,18 +47,18 @@ struct reg { const char* name; /* register name */ int number; /* identifying number */ - uint64_t classes; // bitfield of classes */ + uint32_t attrs; /* bitfield of register attributes */ }; -struct regclass +struct regattr { const char* name; /* class name */ int number; /* identifying number */ }; extern struct reg* makereg(const char* name); -extern void addregclass(struct reg* reg, const char* regclass); -extern struct regclass* getregclass(const char* name); +extern void addregattr(struct reg* reg, const char* regattr); +extern struct regattr* getregattr(const char* name); struct term { /* terminals: */ @@ -82,7 +82,7 @@ struct nonterm Rule chain; /* chain rules w/non-terminal on rhs */ Nonterm link; /* next terminal in number order */ bool is_fragment; /* these instructions are all fragments */ - struct regclass* allocate; /* allocate this kind of register */ + struct regattr* allocate; /* allocate this kind of register */ }; extern void* lookup(const char* name); extern Nonterm nonterm(const char* id, bool allocate); diff --git a/util/mcgg/mcgg.h b/util/mcgg/mcgg.h index a3ff0197b..65dc26f54 100644 --- a/util/mcgg/mcgg.h +++ b/util/mcgg/mcgg.h @@ -61,12 +61,20 @@ extern const struct burm_instruction_data burm_instruction_data[]; struct burm_register_data { const char* name; - uint32_t classes; + uint32_t attrs; }; extern const struct burm_register_data burm_register_data[]; extern const char* burm_register_class_names[]; +enum +{ + REGATTR_BYTES1 = 0, + REGATTR_BYTES2, + REGATTR_BYTES4, + REGATTR_BYTES8 +}; + #endif /* vim: set sw=4 ts=4 expandtab : */