Better management of register data. Add struct hreg.
This commit is contained in:
parent
ac62c34e19
commit
92502901a7
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
32
mach/proto/mcg/reg.c
Normal 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
26
mach/proto/mcg/reg.h
Normal 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 : */
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef VREG_H
|
||||
#define VREG_H
|
||||
|
||||
struct vreg
|
||||
{
|
||||
int id;
|
||||
};
|
||||
|
||||
extern struct vreg* new_vreg(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (p)
|
||||
yyerror("redefinition of '%s'", id);
|
||||
p = calloc(1, sizeof(*p));
|
||||
p->name = id;
|
||||
p->number = number++;
|
||||
smap_put(®isterclasses, id, p);
|
||||
smap_put(®isterattrs, 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(®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; 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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 : */
|
||||
|
|
Loading…
Reference in a new issue