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 "mcgg.h"
#include "hop.h"
#include "vreg.h"
#include "reg.h"
#include "basicblock.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 : */

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

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
: 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);
}
;

View file

@ -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(&registers, 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(&registerclasses, id);
static int number = 1;
struct regattr* p = smap_get(&registerattrs, id);
static int number = 0;
if (!p)
{
if (p)
yyerror("redefinition of '%s'", id);
p = calloc(1, sizeof(*p));
p->name = id;
p->number = number++;
smap_put(&registerclasses, id, p);
smap_put(&registerattrs, id, p);
return p;
}
reg->classes |= 1<<(p->number);
}
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)
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; i<registerclasses.count; i++)
for (i=0; i<registerattrs.count; i++)
{
struct regclass* rc = registerclasses.item[i].right;
assert(rc->number == (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; i<registers.count; i++)
{
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");
}
@ -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)
{

View file

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

View file

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