Better management of register data. Add struct hreg.
This commit is contained in:
parent
ac62c34e19
commit
92502901a7
11 changed files with 141 additions and 87 deletions
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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
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
|
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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
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);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -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(®isters, id);
|
struct reg* p = smap_get(®isters, 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(®isterclasses, id);
|
struct regattr* p = smap_get(®isterattrs, 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(®isterclasses, id, p);
|
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)
|
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 : */
|
||||||
|
|
Loading…
Reference in a new issue