Better management of register data. Add struct hreg.

This commit is contained in:
David Given 2016-10-05 21:00:28 +02:00
parent ac62c34e19
commit 92502901a7
11 changed files with 141 additions and 87 deletions

View file

@ -24,7 +24,7 @@
#include "ir.h" #include "ir.h"
#include "mcgg.h" #include "mcgg.h"
#include "hop.h" #include "hop.h"
#include "vreg.h" #include "reg.h"
#include "basicblock.h" #include "basicblock.h"
#include "procedure.h" #include "procedure.h"

View file

@ -88,4 +88,3 @@ void pass_split_critical_edges(struct procedure* proc)
/* vim: set sw=4 ts=4 expandtab : */ /* vim: set sw=4 ts=4 expandtab : */

32
mach/proto/mcg/reg.c Normal file
View file

@ -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 : */

26
mach/proto/mcg/reg.h Normal file
View file

@ -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 : */

View file

@ -1,28 +1,28 @@
REGISTERS REGISTERS
r0 any int ret; r0 bytes4 int ret;
r1 any int; r1 bytes4 int;
r2 any int; r2 bytes4 int;
r3 any int; r3 bytes4 int;
r4 any int; r4 bytes4 int;
r5 any int; r5 bytes4 int;
r6 any int; r6 bytes4 int;
r7 any int; r7 bytes4 int;
r8 any int; r8 bytes4 int;
r9 any int; r9 bytes4 int;
r10 any int; r10 bytes4 int;
r11 any int; r11 bytes4 int;
s0 any float; s0 bytes4 float;
s1 any float; s1 bytes4 float;
s2 any float; s2 bytes4 float;
s3 any float; s3 bytes4 float;
s4 any float; s4 bytes4 float;
s5 any float; s5 bytes4 float;
s6 any float; s6 bytes4 float;
s7 any float; s7 bytes4 float;
s8 any float; s8 bytes4 float;
s9 any float; s9 bytes4 float;
cc cc; cc cc;

View file

@ -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;
}

View file

@ -1,12 +0,0 @@
#ifndef VREG_H
#define VREG_H
struct vreg
{
int id;
};
extern struct vreg* new_vreg(void);
#endif

View file

@ -74,7 +74,7 @@ registers
register register
: ID { $$ = makereg($1); } : ID { $$ = makereg($1); }
| register ID { $$ = $1; addregclass($1, $2); } | register ID { $$ = $1; addregattr($1, $2); }
; ;
declarations declarations
@ -95,7 +95,7 @@ allocates
$$ = $1; $$ = $1;
if ($$->allocate) if ($$->allocate)
yyerror("pattern type is defined to already allocate a register"); yyerror("pattern type is defined to already allocate a register");
$$->allocate = getregclass($4); $$->allocate = getregattr($4);
} }
; ;

View file

@ -29,11 +29,12 @@ static Rule rules;
static int nrules; static int nrules;
static SMAPOF(struct reg) registers; static SMAPOF(struct reg) registers;
static SMAPOF(struct regclass) registerclasses; static SMAPOF(struct regattr) registerattrs;
static void print(char* fmt, ...); static void print(char* fmt, ...);
static void ckreach(Nonterm p); static void ckreach(Nonterm p);
static void registerterminals(void); static void registerterminals(void);
static struct regattr* makeregattr(const char* id);
static void emitclosure(Nonterm nts); static void emitclosure(Nonterm nts);
static void emitcost(Tree t, const char* v); static void emitcost(Tree t, const char* v);
static void emitcostcalc(Rule r); 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 emitnts(Rule rules, int nrules);
static void emitpredicatedefinitions(Rule rules); static void emitpredicatedefinitions(Rule rules);
static void emitrecord(char* pre, Rule r, int cost); static void emitrecord(char* pre, Rule r, int cost);
static void emitregisterclasses(); static void emitregisterattrs();
static void emitregisters(); static void emitregisters();
static void emitrule(Nonterm nts); static void emitrule(Nonterm nts);
static void emitstate(Term terms, Nonterm start, int ntnumber); static void emitstate(Term terms, Nonterm start, int ntnumber);
@ -125,6 +126,10 @@ int main(int argc, char* argv[])
registerterminals(); registerterminals();
start = nonterm("stmt", true); start = nonterm("stmt", true);
makeregattr("bytes1");
makeregattr("bytes2");
makeregattr("bytes4");
makeregattr("bytes8");
yyin = infp; yyin = infp;
yyparse(); yyparse();
@ -137,7 +142,7 @@ int main(int argc, char* argv[])
yyerror("can't reach non-terminal `%s'\n", p->name); yyerror("can't reach non-terminal `%s'\n", p->name);
#endif #endif
emitregisterclasses(); emitregisterattrs();
emitregisters(); emitregisters();
emitdefs(nts, ntnumber); emitdefs(nts, ntnumber);
emitstruct(nts, ntnumber); emitstruct(nts, ntnumber);
@ -194,7 +199,7 @@ struct entry
struct term t; struct term t;
struct nonterm nt; struct nonterm nt;
struct reg r; struct reg r;
struct regclass rc; struct regattr rc;
} sym; } sym;
struct entry* link; struct entry* link;
} * table[211]; } * table[211];
@ -236,7 +241,7 @@ static void* install(const char* name)
struct reg* makereg(const char* id) struct reg* makereg(const char* id)
{ {
struct reg* p = smap_get(&registers, id); struct reg* p = smap_get(&registers, id);
static int number = 1; static int number = 0;
if (p) if (p)
yyerror("redefinition of '%s'", id); yyerror("redefinition of '%s'", id);
@ -248,25 +253,34 @@ struct reg* makereg(const char* id)
return p; return p;
} }
void addregclass(struct reg* reg, const char* id) struct regattr* makeregattr(const char* id)
{ {
struct regclass* p = smap_get(&registerclasses, id); struct regattr* p = smap_get(&registerattrs, id);
static int number = 1; static int number = 0;
if (!p) if (p)
{ yyerror("redefinition of '%s'", id);
p = calloc(1, sizeof(*p)); p = calloc(1, sizeof(*p));
p->name = id; p->name = id;
p->number = number++; p->number = number++;
smap_put(&registerclasses, id, p); smap_put(&registerattrs, 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(&registerclasses, id); struct regattr* p = smap_get(&registerattrs, id);
if (!p)
p = makeregattr(id);
reg->attrs |= 1<<(p->number);
}
struct regattr* getregattr(const char* id)
{
struct regattr* p = smap_get(&registerattrs, id);
if (!p) if (!p)
yyerror("'%s' is not the name of a register class", id); yyerror("'%s' is not the name of a register class", id);
return p; return p;
@ -318,9 +332,6 @@ Term term(const char* id, int esn)
p->name, p->esn); p->name, p->esn);
p->link = *q; p->link = *q;
*q = p; *q = p;
if (esn != -1)
print("enum { %s = %d };\n", id, esn);
return p; return p;
} }
@ -415,10 +426,6 @@ static void print(char* fmt, ...)
fprintf(outfp, "%x", va_arg(ap, uint32_t)); fprintf(outfp, "%x", va_arg(ap, uint32_t));
break; break;
case 'X':
fprintf(outfp, "0x%" PRIx64 "ULL", va_arg(ap, uint64_t));
break;
case 's': case 's':
fputs(va_arg(ap, char*), outfp); fputs(va_arg(ap, char*), outfp);
break; break;
@ -499,16 +506,15 @@ static void ckreach(Nonterm p)
reach(r->pattern); reach(r->pattern);
} }
static void emitregisterclasses(void) static void emitregisterattrs(void)
{ {
int i; int i;
print("const char* %Pregister_class_names[] = {\n"); print("const char* %Pregister_class_names[] = {\n");
print("%1NULL,\n"); /* register class id 0 is invalid */ for (i=0; i<registerattrs.count; i++)
for (i=0; i<registerclasses.count; i++)
{ {
struct regclass* rc = registerclasses.item[i].right; struct regattr* rc = registerattrs.item[i].right;
assert(rc->number == (i+1)); assert(rc->number == i);
print("%1\"%s\",\n", rc->name); print("%1\"%s\",\n", rc->name);
} }
@ -520,14 +526,14 @@ static void emitregisters(void)
int i; int i;
print("const struct %Pregister_data %Pregister_data[] = {\n"); print("const struct %Pregister_data %Pregister_data[] = {\n");
print("%1{ 0 },\n"); /* register id 0 is invalid */
for (i=0; i<registers.count; i++) for (i=0; i<registers.count; i++)
{ {
struct reg* r = registers.item[i].right; struct reg* r = registers.item[i].right;
assert(r->number == (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"); print("};\n\n");
} }
@ -1168,6 +1174,11 @@ static void emitterms(Term terms)
Term p; Term p;
int k; 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"); print("static const char %Parity[] = {\n");
for (k = 0, p = terms; p; p = p->link) for (k = 0, p = terms; p; p = p->link)
{ {

View file

@ -47,18 +47,18 @@ struct reg
{ {
const char* name; /* register name */ const char* name; /* register name */
int number; /* identifying number */ 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 */ const char* name; /* class name */
int number; /* identifying number */ int number; /* identifying number */
}; };
extern struct reg* makereg(const char* name); extern struct reg* makereg(const char* name);
extern void addregclass(struct reg* reg, const char* regclass); extern void addregattr(struct reg* reg, const char* regattr);
extern struct regclass* getregclass(const char* name); extern struct regattr* getregattr(const char* name);
struct term struct term
{ /* terminals: */ { /* terminals: */
@ -82,7 +82,7 @@ struct nonterm
Rule chain; /* chain rules w/non-terminal on rhs */ Rule chain; /* chain rules w/non-terminal on rhs */
Nonterm link; /* next terminal in number order */ Nonterm link; /* next terminal in number order */
bool is_fragment; /* these instructions are all fragments */ 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 void* lookup(const char* name);
extern Nonterm nonterm(const char* id, bool allocate); extern Nonterm nonterm(const char* id, bool allocate);

View file

@ -61,12 +61,20 @@ extern const struct burm_instruction_data burm_instruction_data[];
struct burm_register_data struct burm_register_data
{ {
const char* name; const char* name;
uint32_t classes; uint32_t attrs;
}; };
extern const struct burm_register_data burm_register_data[]; extern const struct burm_register_data burm_register_data[];
extern const char* burm_register_class_names[]; extern const char* burm_register_class_names[];
enum
{
REGATTR_BYTES1 = 0,
REGATTR_BYTES2,
REGATTR_BYTES4,
REGATTR_BYTES8
};
#endif #endif
/* vim: set sw=4 ts=4 expandtab : */ /* vim: set sw=4 ts=4 expandtab : */