It doesn't really make a lot of sense to have BURG nonterminal names different

to register classes, so combine them. Refactor the map code.
This commit is contained in:
David Given 2016-10-01 12:17:14 +02:00
parent 3a973a19f3
commit 4a3a9a98dc
13 changed files with 331 additions and 194 deletions

View file

@ -17,7 +17,7 @@
#include "em_flag.h" #include "em_flag.h"
#include "em_ptyp.h" #include "em_ptyp.h"
#include "array.h" #include "array.h"
#include "map.h" #include "pmap.h"
#include "diagnostics.h" #include "diagnostics.h"
#include "astring.h" #include "astring.h"
#include "ir.h" #include "ir.h"

View file

@ -1,6 +1,6 @@
#include "mcg.h" #include "mcg.h"
static MAPOF(struct basicblock, struct basicblock) graph; static PMAPOF(struct basicblock, struct basicblock) graph;
static ARRAYOF(struct ir) pops; static ARRAYOF(struct ir) pops;
static ARRAYOF(struct ir) pushes; static ARRAYOF(struct ir) pushes;
@ -46,7 +46,7 @@ static bool collect_outputs_cb(struct ir* ir, void* user)
struct basicblock* caller = user; struct basicblock* caller = user;
if (ir->opcode == IR_BLOCK) if (ir->opcode == IR_BLOCK)
map_addp(&graph, caller, ir->u.bvalue); pmap_add(&graph, caller, ir->u.bvalue);
return false; return false;
} }

View file

@ -1,96 +1,102 @@
REGISTERS REGISTERS
r0 reg4 i ret0; r0 any int ret;
r1 reg4 i; r1 any int;
r2 reg4 i; r2 any int;
r3 reg4 i; r3 any int;
r4 reg4 i; r4 any int;
r5 reg4 i; r5 any int;
r6 reg4 i; r6 any int;
r7 reg4 i; r7 any int;
r8 reg4 i; r8 any int;
r9 reg4 i; r9 any int;
r10 reg4 i; r10 any int;
r11 reg4 i; r11 any int;
s0 reg4 f; s0 any float;
s1 reg4 f; s1 any float;
s2 reg4 f; s2 any float;
s3 reg4 f; s3 any float;
s4 reg4 f; s4 any float;
s5 reg4 f; s5 any float;
s6 reg4 f; s6 any float;
s7 reg4 f; s7 any float;
s8 reg4 f; s8 any float;
s9 reg4 f; s9 any float;
cc cc;
cc conditioncode;
DECLARATIONS DECLARATIONS
address fragment; address fragment;
aluparam fragment; aluparam fragment;
reg allocates(reg4);
tristate allocates(conditioncode);
bistate allocates(conditioncode);
PATTERNS PATTERNS
/* Special */ /* Special */
reg; int;
float;
reg = REG4;
PAIR(BLOCK4, BLOCK4); PAIR(BLOCK4, BLOCK4);
/* Miscellaneous special things */ /* Miscellaneous special things */
PUSH4(in:reg) PUSH4(in:int)
emit "push %in" emit "push %in"
cost 4; cost 4;
reg = POP4 int = POP4
emit "pop %reg" emit "pop %int"
cost 4; cost 4;
RET RET
emit "ret" emit "ret"
cost 4; cost 4;
SETRET4(in:reg) SETRET4(in:ret)
emit "mov r0, %in" emit "mov r0, %in"
cost 4; cost 4;
int = REG4 cost 1;
float = REG4 cost 1;
any = int cost 1;
int = any cost 1;
any = float cost 1;
float = any cost 1;
/* Memory operations */ /* Memory operations */
STORE4(addr:address, value:reg) STORE4(addr:address, value:int)
emit "str %value, %addr" emit "str %value, %addr"
cost 4; cost 4;
reg = LOAD4(addr:address) int = LOAD4(addr:address)
emit "ldr %reg, %addr" emit "ldr %int, %addr"
cost 4; cost 4;
reg = LOAD1(addr:address) int = LOAD1(addr:address)
emit "ldrb %reg, %addr" emit "ldrb %int, %addr"
cost 4; cost 4;
reg = CIU14(LOAD1(addr:address)) int = CIU14(LOAD1(addr:address))
emit "ldrb %reg, %addr" emit "ldrb %int, %addr"
cost 4; cost 4;
reg = CII14(CIU41(CIU14(LOAD1(addr:address)))) int = CII14(CIU41(CIU14(LOAD1(addr:address))))
emit "ldrsb %reg, %addr" emit "ldrsb %int, %addr"
cost 4; cost 4;
/* Locals */ /* Locals */
reg = in:LOCAL4 int = in:LOCAL4
emit "add %reg, fp, #$in" emit "add %int, fp, #$in"
cost 4; cost 4;
address = in:LOCAL4 address = in:LOCAL4
@ -99,10 +105,10 @@ PATTERNS
/* Memory addressing modes */ /* Memory addressing modes */
address = ADD4(addr:reg, offset:CONST4) address = ADD4(addr:int, offset:CONST4)
emit "[%addr, #$offset]"; emit "[%addr, #$offset]";
address = addr:reg address = addr:int
emit "[%addr]"; emit "[%addr]";
@ -112,12 +118,7 @@ PATTERNS
emit "b $addr" emit "b $addr"
cost 4; cost 4;
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4)) CJUMPEQ(value:cc, PAIR(true:BLOCK4, false:BLOCK4))
emit "beq $true"
emit "b $false"
cost 8;
CJUMPEQ(value:bistate, PAIR(true:BLOCK4, false:BLOCK4))
emit "beq $true" emit "beq $true"
emit "b $false" emit "b $false"
cost 8; cost 8;
@ -125,72 +126,67 @@ PATTERNS
/* Comparisons */ /* Comparisons */
tristate = COMPARES4(left:reg, right:aluparam) cc = COMPARES4(left:int, right:aluparam)
emit "cmp %left, %right" emit "cmp %left, %right"
cost 4; cost 4;
bistate = COMPARES4(COMPARES4(left:reg, right:aluparam), CONST4) cc = COMPARES4(COMPARES4(left:int, right:aluparam), CONST4)
emit "cmp %left, %right" emit "cmp %left, %right"
cost 4; cost 4;
reg = tristate int = cc
emit "mov %reg, #0" emit "mov %int, #0"
emit "movlt %reg, #-1" emit "movlt %int, #-1"
emit "movgt %reg, #1" emit "movgt %int, #1"
cost 12; cost 12;
reg = bistate
emit "moveq %reg, #1"
emit "movne %reg, #0"
cost 8;
/* Conversions */ /* Conversions */
reg = CII14(CIU41(value:reg)) int = CII14(CIU41(value:int))
emit "sxtb %reg, %value" emit "sxtb %int, %value"
cost 4; cost 4;
reg = CIU41(in:reg) int = CIU41(in:int)
emit "and %reg, %in, #0xff" emit "and %int, %in, #0xff"
cost 4; cost 4;
/* ALU operations */ /* ALU operations */
reg = ADD4(left:reg, right:aluparam) int = ADD4(left:int, right:aluparam)
emit "add %reg, %left, %right" emit "add %int, %left, %right"
cost 4; cost 4;
reg = ADD4(left:aluparam, right:reg) int = ADD4(left:aluparam, right:int)
emit "add %reg, %right, %left" emit "add %int, %right, %left"
cost 4; cost 4;
aluparam = value:CONST4 aluparam = value:CONST4
emit "#$value"; emit "#$value";
aluparam = value:reg aluparam = value:int
emit "%value"; emit "%value";
reg = value:aluparam int = value:aluparam
emit "mov %reg, %value" emit "mov %int, %value"
cost 4; cost 4;
reg = value:LABEL4 int = value:LABEL4
emit "adr %reg, $value" emit "adr %int, $value"
cost 4; cost 4;
reg = value:BLOCK4 int = value:BLOCK4
emit "adr %reg, $value" emit "adr %int, $value"
cost 4; cost 4;
reg = value:CONST4 any = value:CONST4
emit "ldr %reg, #$value" emit "ldr %any, address-containing-$value"
cost 8; cost 8;
/* FPU operations */ /* FPU operations */
reg = ADDF4(left:reg, right:reg) float = ADDF4(left:float, right:float)
emit "fadds %reg, %left, %right" emit "fadds %float, %left, %right"
cost 4; cost 4;

View file

@ -56,3 +56,19 @@ void imap_add(void* mapp, int left, void* right)
append(map, left, right); append(map, left, right);
} }
void* imap_get(void* mapp, int left)
{
struct imap* map = mapp;
int i;
for (i=0; i<map->count; i++)
{
struct imap_node* node = &map->item[i];
if (node->left == left)
return node->right;
}
return NULL;
}

View file

@ -25,6 +25,7 @@ struct imap
extern void imap_put(void* map, int left, void* right); extern void imap_put(void* map, int left, void* right);
extern void imap_add(void* map, int left, void* right); extern void imap_add(void* map, int left, void* right);
extern void* imap_get(void* map, int left);
#endif #endif

View file

@ -1,30 +0,0 @@
#ifndef MAP_H
#define MAP_H
struct map_node
{
void* left;
void* right;
};
/* Danger, Will Robinson! The type and the macro must be compatible. */
struct map
{
struct map_node* item;
int count;
int max;
};
#define MAPOF(LEFT, RIGHT) \
struct { \
struct { LEFT* left; RIGHT* right; }* item; \
int count; \
int max; \
}
extern void map_putp(void* map, void* left, void* right);
extern void map_addp(void* map, void* left, void* right);
#endif

View file

@ -1,16 +1,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include "map.h" #include "pmap.h"
static void append(void* mapp, void* left, void* right) static void append(void* mapp, void* left, void* right)
{ {
struct map* map = mapp; struct pmap* map = mapp;
struct map_node* node; struct pmap_node* node;
if (map->count == map->max) if (map->count == map->max)
{ {
int newmax = (map->max == 0) ? 8 : (map->max * 2); int newmax = (map->max == 0) ? 8 : (map->max * 2);
struct map_node* newarray = realloc(map->item, newmax * sizeof(*newarray)); struct pmap_node* newarray = realloc(map->item, newmax * sizeof(*newarray));
map->max = newmax; map->max = newmax;
map->item = newarray; map->item = newarray;
@ -23,14 +23,14 @@ static void append(void* mapp, void* left, void* right)
node->right = right; node->right = right;
} }
void map_putp(void* mapp, void* left, void* right) void pmap_put(void* mapp, void* left, void* right)
{ {
struct map* map = mapp; struct pmap* map = mapp;
int i; int i;
for (i=0; i<map->count; i++) for (i=0; i<map->count; i++)
{ {
struct map_node* node = &map->item[i]; struct pmap_node* node = &map->item[i];
if (node->left == left) if (node->left == left)
{ {
node->right = right; node->right = right;
@ -41,14 +41,14 @@ void map_putp(void* mapp, void* left, void* right)
append(map, left, right); append(map, left, right);
} }
void map_addp(void* mapp, void* left, void* right) void pmap_add(void* mapp, void* left, void* right)
{ {
struct map* map = mapp; struct pmap* map = mapp;
int i; int i;
for (i=0; i<map->count; i++) for (i=0; i<map->count; i++)
{ {
struct map_node* node = &map->item[i]; struct pmap_node* node = &map->item[i];
if ((node->left == left) && (node->right == right)) if ((node->left == left) && (node->right == right))
return; return;
} }
@ -56,3 +56,19 @@ void map_addp(void* mapp, void* left, void* right)
append(map, left, right); append(map, left, right);
} }
void* pmap_get(void* mapp, void* left)
{
struct pmap* map = mapp;
int i;
for (i=0; i<map->count; i++)
{
struct pmap_node* node = &map->item[i];
if (node->left == left)
return node->right;
}
return NULL;
}

31
modules/src/data/pmap.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef PMAP_H
#define PMAP_H
struct pmap_node
{
void* left;
void* right;
};
/* Danger, Will Robinson! The type and the macro must be compatible. */
struct pmap
{
struct pmap_node* item;
int count;
int max;
};
#define PMAPOF(LEFT, RIGHT) \
struct { \
struct { LEFT* left; RIGHT* right; }* item; \
int count; \
int max; \
}
extern void pmap_put(void* map, void* left, void* right);
extern void pmap_add(void* map, void* left, void* right);
extern void* pmap_get(void* map, void* left);
#endif

74
modules/src/data/smap.c Normal file
View file

@ -0,0 +1,74 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "smap.h"
static void append(void* mapp, const char* left, void* right)
{
struct smap* map = mapp;
struct smap_node* node;
if (map->count == map->max)
{
int newmax = (map->max == 0) ? 8 : (map->max * 2);
struct smap_node* newarray = realloc(map->item, newmax * sizeof(*newarray));
map->max = newmax;
map->item = newarray;
}
node = &map->item[map->count];
map->count++;
node->left = left;
node->right = right;
}
void smap_put(void* mapp, const char* left, void* right)
{
struct smap* map = mapp;
int i;
for (i=0; i<map->count; i++)
{
struct smap_node* node = &map->item[i];
if (strcmp(node->left, left) == 0)
{
node->right = right;
return;
}
}
append(map, left, right);
}
void smap_add(void* mapp, const char* left, void* right)
{
struct smap* map = mapp;
int i;
for (i=0; i<map->count; i++)
{
struct smap_node* node = &map->item[i];
if ((strcmp(node->left, left) == 0) && (node->right == right))
return;
}
append(map, left, right);
}
void* smap_get(void* mapp, const char* left)
{
struct smap* map = mapp;
int i;
for (i=0; i<map->count; i++)
{
struct smap_node* node = &map->item[i];
if (strcmp(node->left, left) == 0)
return node->right;
}
return NULL;
}

31
modules/src/data/smap.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef SMAP_H
#define SMAP_H
struct smap_node
{
const char* left;
void* right;
};
/* Danger, Will Robinson! The type and the macro must be compatible. */
struct smap
{
struct smap_node* item;
int count;
int max;
};
#define SMAPOF(RIGHT) \
struct { \
struct { const char* left; RIGHT* right; }* item; \
int count; \
int max; \
}
extern void smap_put(void* map, const char* left, void* right);
extern void smap_add(void* map, const char* left, void* right);
extern void* smap_get(void* map, const char* left);
#endif

View file

@ -22,7 +22,7 @@ static int nextern = 1;
Rule rule; Rule rule;
struct reg* reg; struct reg* reg;
struct stringlist* stringlist; struct stringlist* stringlist;
char* stringpair[2]; struct terminfo terminfo;
} }
%term ALLOCATES %term ALLOCATES
@ -48,7 +48,7 @@ static int nextern = 1;
%type <rule> pattern %type <rule> pattern
%type <stringlist> cfragments %type <stringlist> cfragments
%type <stringlist> qfragments %type <stringlist> qfragments
%type <stringpair> labelledid %type <terminfo> terminfo
%type <tree> rhs %type <tree> rhs
%% %%
@ -106,14 +106,16 @@ pattern
; ;
rhs rhs
: labelledid { $$ = tree($1[1], $1[0], NULL, NULL); } : terminfo { $$ = tree(&$1, NULL, NULL); }
| labelledid '(' rhs ')' { $$ = tree($1[1], $1[0], $3, NULL); } | terminfo '(' rhs ')' { $$ = tree(&$1, $3, NULL); }
| labelledid '(' rhs ',' rhs ')' { $$ = tree($1[1], $1[0], $3, $5); } | terminfo '(' rhs ',' rhs ')' { $$ = tree(&$1, $3, $5); }
; ;
labelledid terminfo
: ID { $$[0] = NULL; $$[1] = $1; } : ID { $$.name = $1; }
| ID ':' ID { $$[0] = $1; $$[1] = $3; } | ID '.' ID { $$.name = $1; $$.regattr = $3; }
| ID ':' ID { $$.label = $1; $$.name = $3; }
| ID ':' ID '.' ID { $$.label = $1; $$.name = $3; $$.regattr = $5; }
; ;
cfragments cfragments

View file

@ -9,9 +9,11 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h>
#include "iburg.h" #include "iburg.h"
#include "ircodes.h" #include "ircodes.h"
#include "astring.h" #include "astring.h"
#include "smap.h"
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id$";
@ -21,13 +23,14 @@ static char* prefix = "burm";
static int Tflag = 1; /* tracing */ static int Tflag = 1; /* tracing */
static int ntnumber = 0; static int ntnumber = 0;
static Nonterm start = 0; static Nonterm start = 0;
static struct reg* regs = NULL;
static struct regclass* regclasses = NULL;
static Term terms; static Term terms;
static Nonterm nts; static Nonterm nts;
static Rule rules; static Rule rules;
static int nrules; static int nrules;
static SMAPOF(struct reg) registers;
static SMAPOF(struct regclass) registerclasses;
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);
@ -44,8 +47,8 @@ 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(struct regclass* rc); static void emitregisterclasses();
static void emitregisters(struct reg* regs); 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);
static void emitstring(Rule rules); static void emitstring(Rule rules);
@ -128,12 +131,14 @@ int main(int argc, char* argv[])
if (start) if (start)
ckreach(start); ckreach(start);
#if 0
for (p = nts; p; p = p->link) for (p = nts; p; p = p->link)
if (!p->reached) if (!p->reached)
yyerror("can't reach non-terminal `%s'\n", p->name); yyerror("can't reach non-terminal `%s'\n", p->name);
#endif
emitregisterclasses(regclasses); emitregisterclasses();
emitregisters(regs); emitregisters();
emitdefs(nts, ntnumber); emitdefs(nts, ntnumber);
emitstruct(nts, ntnumber); emitstruct(nts, ntnumber);
emitnts(rules, nrules); emitnts(rules, nrules);
@ -230,52 +235,40 @@ static void* install(const char* name)
struct reg* makereg(const char* id) struct reg* makereg(const char* id)
{ {
struct reg* p = lookup(id); struct reg* p = smap_get(&registers, id);
struct reg** q = &regs;
static int number = 1; static int number = 1;
if (p) if (p)
yyerror("redefinition of '%s'", id); yyerror("redefinition of '%s'", id);
p = install(id); p = calloc(1, sizeof(*p));
p->kind = REG; p->name = id;
p->number = number++; p->number = number++;
smap_put(&registers, id, p);
while (*q && (*q)->number < p->number)
q = &(*q)->link;
assert(*q == 0 || (*q)->number != p->number);
p->link = *q;
*q = p;
return p; return p;
} }
void addregclass(struct reg* reg, const char* id) void addregclass(struct reg* reg, const char* id)
{ {
struct regclass* p = lookup(id); struct regclass* p = smap_get(&registerclasses, id);
struct regclass** q = &regclasses;
static int number = 1; static int number = 1;
if (p && (p->kind != REGCLASS))
yyerror("redefinition of '%s' as something else\n", id);
if (!p) if (!p)
{ {
p = install(id); p = calloc(1, sizeof(*p));
p->kind = REGCLASS; p->name = id;
p->number = number++; p->number = number++;
smap_put(&registerclasses, id, p);
while (*q && (*q)->number < p->number)
q = &(*q)->link;
assert(*q == 0 || (*q)->number != p->number);
p->link = *q;
*q = p;
} }
reg->classes |= 1<<(p->number); reg->classes |= 1<<(p->number);
nonterm(id, true);
} }
struct regclass* getregclass(const char* id) struct regclass* getregclass(const char* id)
{ {
struct regclass* p = lookup(id); struct regclass* p = smap_get(&registerclasses, id);
if (!p || (p->kind != REGCLASS)) 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;
} }
@ -333,10 +326,10 @@ Term term(const char* id, int esn)
} }
/* tree - create & initialize a tree node with the given fields */ /* tree - create & initialize a tree node with the given fields */
Tree tree(const char* id, const char* label, Tree left, Tree right) Tree tree(struct terminfo* ti, Tree left, Tree right)
{ {
Tree t = calloc(1, sizeof *t); Tree t = calloc(1, sizeof *t);
Term p = lookup(id); Term p = lookup(ti->name);
int arity = 0; int arity = 0;
if (left && right) if (left && right)
@ -345,22 +338,22 @@ Tree tree(const char* id, const char* label, Tree left, Tree right)
arity = 1; arity = 1;
if (p == NULL && arity > 0) if (p == NULL && arity > 0)
{ {
yyerror("undefined terminal `%s'\n", id); yyerror("undefined terminal `%s'\n", ti->name);
p = term(id, -1); p = term(ti->name, -1);
} }
else if (p == NULL && arity == 0) else if (p == NULL && arity == 0)
p = (Term)nonterm(id, false); p = (Term)nonterm(ti->name, false);
else if (p && p->kind == NONTERM && arity > 0) else if (p && p->kind == NONTERM && arity > 0)
{ {
yyerror("`%s' is a non-terminal\n", id); yyerror("`%s' is a non-terminal\n", ti->name);
p = term(id, -1); p = term(ti->name, -1);
} }
if (p->kind == TERM && p->arity == -1) if (p->kind == TERM && p->arity == -1)
p->arity = arity; p->arity = arity;
if (p->kind == TERM && arity != p->arity) if (p->kind == TERM && arity != p->arity)
yyerror("inconsistent arity for terminal `%s'\n", id); yyerror("inconsistent arity for terminal `%s'\n", ti->name);
t->op = p; t->op = p;
t->label = label; t->label = ti->label;
t->nterms = p->kind == TERM; t->nterms = p->kind == TERM;
if (t->left = left) if (t->left = left)
t->nterms += left->nterms; t->nterms += left->nterms;
@ -423,6 +416,10 @@ 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;
@ -503,34 +500,34 @@ static void ckreach(Nonterm p)
reach(r->pattern); reach(r->pattern);
} }
static void emitregisterclasses(struct regclass* rc) static void emitregisterclasses(void)
{ {
int k = 0; int i;
print("const char* %Pregister_class_names[] = {\n"); print("const char* %Pregister_class_names[] = {\n");
while (rc) print("%1NULL,\n"); /* register class id 0 is invalid */
for (i=0; i<registerclasses.count; i++)
{ {
for (; k < rc->number; k++) struct regclass* rc = registerclasses.item[i].right;
print("%1NULL,\n"); assert(rc->number == (i+1));
k++;
print("%1\"%s\",\n", rc->name); print("%1\"%s\",\n", rc->name);
rc = rc->link;
} }
print("};\n\n"); print("};\n\n");
} }
static void emitregisters(struct reg* r) static void emitregisters(void)
{ {
int k = 0; int i;
print("const struct %Pregister_data %Pregister_data[] = {\n");
while (r)
{
for (; k < r->number; k++)
print("%1{ 0 },\n");
k++;
print("%1{ \"%s\", %d },\n", r->name, r->classes); print("const struct %Pregister_data %Pregister_data[] = {\n");
r = r->link; 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));
print("%1{ \"%s\", %X },\n", r->name, r->classes);
} }
print("};\n\n"); print("};\n\n");
} }

View file

@ -15,21 +15,24 @@ typedef enum
typedef struct rule* Rule; typedef struct rule* Rule;
typedef struct term* Term; typedef struct term* Term;
struct terminfo
{
const char* name;
const char* label;
const char* regattr;
};
struct reg struct reg
{ {
const char* name; /* register name */ const char* name; /* register name */
Kind kind; /* REG */
int number; /* identifying number */ int number; /* identifying number */
uint32_t classes; // bitfield of classes */ uint64_t classes; // bitfield of classes */
struct reg* link; /* next in list */
}; };
struct regclass struct regclass
{ {
const char* name; /* class name */ const char* name; /* class name */
Kind kind; /* REGCLASS */
int number; /* identifying number */ int number; /* identifying number */
struct regclass* link; /* next in list */
}; };
extern struct reg* makereg(const char* name); extern struct reg* makereg(const char* name);
@ -72,7 +75,7 @@ struct tree
Tree left, right; /* operands */ Tree left, right; /* operands */
int nterms; /* number of terminal nodes in this tree */ int nterms; /* number of terminal nodes in this tree */
}; };
extern Tree tree(const char* op, const char* label, Tree left, Tree right); extern Tree tree(struct terminfo* ti, Tree left, Tree right);
struct rule struct rule
{ /* rules: */ { /* rules: */