Collapse several rule arrays into one; actually generate the array properly.
This commit is contained in:
parent
67eb21d428
commit
bde5792b1a
4 changed files with 93 additions and 76 deletions
|
@ -25,8 +25,9 @@ static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
|
void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
|
||||||
|
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
|
||||||
tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
|
tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
|
||||||
burm_string[ruleno], cost, bestcost);
|
insndata->name, cost, bestcost);
|
||||||
}
|
}
|
||||||
|
|
||||||
void burm_panic_cannot_match(struct ir* ir)
|
void burm_panic_cannot_match(struct ir* ir)
|
||||||
|
@ -41,6 +42,7 @@ static void queue_instructions(struct ir* ir, int goal)
|
||||||
{
|
{
|
||||||
struct ir* children[10];
|
struct ir* children[10];
|
||||||
int ruleno = burm_rule(ir->state_label, goal);
|
int ruleno = burm_rule(ir->state_label, goal);
|
||||||
|
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
|
||||||
const short* nts = burm_nts[ruleno];
|
const short* nts = burm_nts[ruleno];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -48,7 +50,11 @@ static void queue_instructions(struct ir* ir, int goal)
|
||||||
for (i=0; nts[i]; i++)
|
for (i=0; nts[i]; i++)
|
||||||
queue_instructions(children[i], nts[i]);
|
queue_instructions(children[i], nts[i]);
|
||||||
|
|
||||||
tracef('I', "I: $%d selected insn %d: %s\n", ir->id, ruleno, burm_string[ruleno]);
|
tracef('I', "I: $%d selected %s %d: %s\n",
|
||||||
|
ir->id,
|
||||||
|
insndata->is_fragment ? "fragment" : "instruction",
|
||||||
|
ruleno,
|
||||||
|
insndata->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_instructions(struct basicblock* bb)
|
static void select_instructions(struct basicblock* bb)
|
||||||
|
|
|
@ -43,21 +43,25 @@ PATTERNS
|
||||||
emit "ldrb %reg, %addr"
|
emit "ldrb %reg, %addr"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
|
reg = CII14(CIU41(CIU14(LOAD1(addr:address))))
|
||||||
|
emit "ldrsb %reg, %addr"
|
||||||
|
cost 4;
|
||||||
|
|
||||||
|
|
||||||
/* Locals */
|
/* Locals */
|
||||||
|
|
||||||
reg = in:LOCAL4
|
reg = in:LOCAL4
|
||||||
emit "add %reg, fp, #%in"
|
emit "add %reg, fp, #$in"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
address = in:LOCAL4
|
address = in:LOCAL4
|
||||||
fragment "[fp, #%in]";
|
fragment "[fp, #$in]";
|
||||||
|
|
||||||
|
|
||||||
/* Memory addressing modes */
|
/* Memory addressing modes */
|
||||||
|
|
||||||
address = ADD4(addr:reg, offset:CONST)
|
address = ADD4(addr:reg, offset:CONST)
|
||||||
fragment "[%addr, #%offset]";
|
fragment "[%addr, #$offset]";
|
||||||
|
|
||||||
address = addr:reg
|
address = addr:reg
|
||||||
fragment "[%addr]";
|
fragment "[%addr]";
|
||||||
|
@ -66,12 +70,12 @@ PATTERNS
|
||||||
/* Branches */
|
/* Branches */
|
||||||
|
|
||||||
JUMP(addr:BLOCK4)
|
JUMP(addr:BLOCK4)
|
||||||
emit "b %addr"
|
emit "b $addr"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
|
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
|
||||||
emit "beq %true"
|
emit "beq $true"
|
||||||
emit "bne %false"
|
emit "bne $false"
|
||||||
cost 8;
|
cost 8;
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +115,7 @@ PATTERNS
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
aluparam = value:CONST4
|
aluparam = value:CONST4
|
||||||
fragment "#%value.ivalue";
|
fragment "#$value";
|
||||||
|
|
||||||
aluparam = reg;
|
aluparam = reg;
|
||||||
|
|
||||||
|
@ -120,13 +124,13 @@ PATTERNS
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
reg = value:LABEL4
|
reg = value:LABEL4
|
||||||
emit "adr %reg, %value"
|
emit "adr %reg, $value"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
reg = value:BLOCK4
|
reg = value:BLOCK4
|
||||||
emit "adr %reg, %value"
|
emit "adr %reg, $value"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
reg = value:CONST4
|
reg = value:CONST4
|
||||||
emit "ldr %reg, #value"
|
emit "ldr %reg, #$value"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
|
@ -41,7 +41,7 @@ static void emitnts(Rule rules, int nrules);
|
||||||
static void emitrecord(char* pre, Rule r, int cost);
|
static void emitrecord(char* pre, Rule r, int cost);
|
||||||
static void emitrule(Nonterm nts);
|
static void emitrule(Nonterm nts);
|
||||||
static void emitpredicatedefinitions(Rule rules);
|
static void emitpredicatedefinitions(Rule rules);
|
||||||
static void emitemitters(Rule rules);
|
static void emitinsndata(Rule rules);
|
||||||
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);
|
||||||
static void emitstruct(Nonterm nts, int ntnumber);
|
static void emitstruct(Nonterm nts, int ntnumber);
|
||||||
|
@ -135,7 +135,7 @@ int main(int argc, char* argv[])
|
||||||
emitrule(nts);
|
emitrule(nts);
|
||||||
emitclosure(nts);
|
emitclosure(nts);
|
||||||
emitpredicatedefinitions(rules);
|
emitpredicatedefinitions(rules);
|
||||||
emitemitters(rules);
|
emitinsndata(rules);
|
||||||
if (start)
|
if (start)
|
||||||
emitstate(terms, start, ntnumber);
|
emitstate(terms, start, ntnumber);
|
||||||
print("#ifdef STATE_LABEL\n");
|
print("#ifdef STATE_LABEL\n");
|
||||||
|
@ -800,59 +800,51 @@ static void emitpredicatedefinitions(Rule r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emittreefetchers(uint32_t path, Tree tree)
|
static void print_path(uint32_t path)
|
||||||
{
|
{
|
||||||
if (tree->label)
|
int i = 0;
|
||||||
|
|
||||||
|
while (path > 0)
|
||||||
{
|
{
|
||||||
int i = 0;
|
switch (path % 3)
|
||||||
uint32_t p = path;
|
|
||||||
print("%1NODEPTR_TYPE node_%s = ", tree->label);
|
|
||||||
while (p > 0)
|
|
||||||
{
|
{
|
||||||
switch (p % 3)
|
case 1: print("LEFT_CHILD("); break;
|
||||||
{
|
case 2: print("RIGHT_CHILD("); break;
|
||||||
case 1: print("LEFT_CHILD("); break;
|
|
||||||
case 2: print("RIGHT_CHILD("); break;
|
|
||||||
}
|
|
||||||
p /= 3;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
path /= 3;
|
||||||
print("node");
|
i++;
|
||||||
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
print(")");
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
print(";\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->left)
|
print("node");
|
||||||
emittreefetchers(path*3 + 1, tree->left);
|
|
||||||
if (tree->right)
|
while (i > 0)
|
||||||
emittreefetchers(path*3 + 2, tree->right);
|
{
|
||||||
|
print(")");
|
||||||
|
i--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Tree find_label(Tree root, const char* name)
|
static const uint32_t PATH_MISSING = 0xffffffff;
|
||||||
|
|
||||||
|
static uint32_t find_label(Tree root, const char* name, uint32_t path)
|
||||||
{
|
{
|
||||||
Tree t;
|
uint32_t p;
|
||||||
|
|
||||||
if (root->label && (strcmp(root->label, name) == 0))
|
if (root->label && (strcmp(root->label, name) == 0))
|
||||||
return root;
|
return path;
|
||||||
|
|
||||||
t = NULL;
|
p = PATH_MISSING;
|
||||||
if (root->left && !t)
|
if (root->left && (p == PATH_MISSING))
|
||||||
t = find_label(root->left, name);
|
p = find_label(root->left, name, path*3 + 1);
|
||||||
if (root->right && !t)
|
if (root->right && (p == PATH_MISSING))
|
||||||
t = find_label(root->right, name);
|
p = find_label(root->right, name, path*3 + 2);
|
||||||
return t;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* emitemitters - emit the code generation routines */
|
/* emitinsndata - emit the code generation data */
|
||||||
static void emitemitters(Rule rules)
|
static void emitinsndata(Rule rules)
|
||||||
{
|
{
|
||||||
|
int k;
|
||||||
Rule r;
|
Rule r;
|
||||||
|
|
||||||
r = rules;
|
r = rules;
|
||||||
|
@ -863,8 +855,6 @@ static void emitemitters(Rule rules)
|
||||||
{
|
{
|
||||||
print("/* %R */\n", r);
|
print("/* %R */\n", r);
|
||||||
print("static void %Pemitter_%d(NODEPTR_TYPE node, struct %Pemitter_data* data) {\n", r->ern);
|
print("static void %Pemitter_%d(NODEPTR_TYPE node, struct %Pemitter_data* data) {\n", r->ern);
|
||||||
emittreefetchers(0, r->pattern);
|
|
||||||
print("%1NODEPTR_TYPE node_%s = node;\n", r->lhs->name);
|
|
||||||
|
|
||||||
while (f)
|
while (f)
|
||||||
{
|
{
|
||||||
|
@ -873,14 +863,22 @@ static void emitemitters(Rule rules)
|
||||||
case '%':
|
case '%':
|
||||||
{
|
{
|
||||||
const char* label = f->data + 1;
|
const char* label = f->data + 1;
|
||||||
Tree t = find_label(r->pattern, label);
|
|
||||||
if (!t && (strcmp(label, r->lhs->name) != 0))
|
print("%1data->emit_ir(");
|
||||||
|
if (strcmp(label, r->lhs->name) == 0)
|
||||||
|
print("node");
|
||||||
|
else
|
||||||
{
|
{
|
||||||
yylineno = r->lineno;
|
uint32_t path = find_label(r->pattern, label, 0);
|
||||||
yyerror("label '%s' not found", label);
|
if (path == PATH_MISSING)
|
||||||
exit(1);
|
{
|
||||||
|
yylineno = r->lineno;
|
||||||
|
yyerror("label '%s' not found", label);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
print_path(path);
|
||||||
}
|
}
|
||||||
print("%1data->emit_ir(node_%s);\n", label);
|
print(");\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,18 +901,27 @@ static void emitemitters(Rule rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = rules;
|
r = rules;
|
||||||
print("%Pemitter_t* const %Pemitters[] = {\n");
|
print("const struct %Pinstruction_data %Pinstruction_data[] = {\n");
|
||||||
|
k = 0;
|
||||||
while (r)
|
while (r)
|
||||||
{
|
{
|
||||||
struct stringfragment* f = r->code.first;
|
for (; k < r->ern; k++)
|
||||||
|
print("%1{ 0 }, /* %d */\n", k);
|
||||||
|
k++;
|
||||||
|
|
||||||
print("%1");
|
print("%1{ /* %d: %R */\n", r->ern, r);
|
||||||
if (f)
|
|
||||||
print("&%Pemitter_%d,", r->ern);
|
print("%2\"%R\",\n", r);
|
||||||
|
|
||||||
|
print("%2");
|
||||||
|
if (r->code.first)
|
||||||
|
print("&%Pemitter_%d,\n", r->ern);
|
||||||
else
|
else
|
||||||
print("NULL,");
|
print("NULL,\n");
|
||||||
print(" /* %R */\n", r);
|
|
||||||
|
|
||||||
|
print("%2%s,\n", r->is_fragment ? "true" : "false");
|
||||||
|
|
||||||
|
print("%1},\n");
|
||||||
r = r->link;
|
r = r->link;
|
||||||
}
|
}
|
||||||
print("};\n\n");
|
print("};\n\n");
|
||||||
|
@ -971,13 +978,6 @@ static void emitstring(Rule rules)
|
||||||
print("%1{ 0 },%1/* %d */\n", k);
|
print("%1{ 0 },%1/* %d */\n", k);
|
||||||
print("%1{ %d },%1/* %d = %R */\n", r->cost, k++, r);
|
print("%1{ %d },%1/* %d = %R */\n", r->cost, k++, r);
|
||||||
}
|
}
|
||||||
print("};\n\nconst char *%Pstring[] = {\n");
|
|
||||||
for (k = 0, r = rules; r; r = r->link)
|
|
||||||
{
|
|
||||||
for (; k < r->ern; k++)
|
|
||||||
print("%1/* %d */%10,\n", k);
|
|
||||||
print("%1/* %d */%1\"%R\",\n", k++, r);
|
|
||||||
}
|
|
||||||
print("};\n\n");
|
print("};\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ typedef struct ir* NODEPTR_TYPE;
|
||||||
|
|
||||||
extern void* burm_label(struct ir* ir);
|
extern void* burm_label(struct ir* ir);
|
||||||
extern int burm_rule(void* state, int goalnt);
|
extern int burm_rule(void* state, int goalnt);
|
||||||
extern const char* burm_string[];
|
|
||||||
extern const short *burm_nts[];
|
extern const short *burm_nts[];
|
||||||
extern struct ir** burm_kids(struct ir* p, int eruleno, struct ir* kids[]);
|
extern struct ir** burm_kids(struct ir* p, int eruleno, struct ir* kids[]);
|
||||||
extern void burm_trace(struct ir* p, int ruleno, int cost, int bestcost);
|
extern void burm_trace(struct ir* p, int ruleno, int cost, int bestcost);
|
||||||
|
@ -34,7 +33,15 @@ struct burm_emitter_data
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data);
|
typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data);
|
||||||
extern burm_emitter_t* const burm_emitters[];
|
|
||||||
|
struct burm_instruction_data
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
burm_emitter_t* emitter;
|
||||||
|
bool is_fragment;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct burm_instruction_data burm_instruction_data[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue