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