#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)
{
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;
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)
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]";
/* 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;
cost 4;
aluparam = value:CONST4
- fragment "#%value.ivalue";
+ fragment "#$value";
aluparam = reg;
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;
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);
emitrule(nts);
emitclosure(nts);
emitpredicatedefinitions(rules);
- emitemitters(rules);
+ emitinsndata(rules);
if (start)
emitstate(terms, start, ntnumber);
print("#ifdef STATE_LABEL\n");
}
}
-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;
}
+ path /= 3;
+ i++;
+ }
- print("node");
+ print("node");
- while (i > 0)
- {
- print(")");
- i--;
- }
-
- print(";\n");
+ while (i > 0)
+ {
+ print(")");
+ i--;
}
-
- if (tree->left)
- emittreefetchers(path*3 + 1, tree->left);
- if (tree->right)
- emittreefetchers(path*3 + 2, tree->right);
}
-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;
{
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)
{
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;
}
}
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");
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");
}