From bde5792b1a202174f95efaece3bd9af3b16195db Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 25 Sep 2016 17:14:54 +0200 Subject: [PATCH] Collapse several rule arrays into one; actually generate the array properly. --- mach/proto/mcg/pass_instructionselection.c | 10 +- mach/proto/mcg/table | 24 ++-- util/mcgg/iburg.c | 122 ++++++++++----------- util/mcgg/mcgg.h | 11 +- 4 files changed, 92 insertions(+), 75 deletions(-) diff --git a/mach/proto/mcg/pass_instructionselection.c b/mach/proto/mcg/pass_instructionselection.c index e54b6ea75..bfdaa77bd 100644 --- a/mach/proto/mcg/pass_instructionselection.c +++ b/mach/proto/mcg/pass_instructionselection.c @@ -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) diff --git a/mach/proto/mcg/table b/mach/proto/mcg/table index efaffdc36..9146f6339 100644 --- a/mach/proto/mcg/table +++ b/mach/proto/mcg/table @@ -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; diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index c4189f560..399ebdd85 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -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; } + 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; @@ -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"); } diff --git a/util/mcgg/mcgg.h b/util/mcgg/mcgg.h index 1a1be1b83..1279ee0ec 100644 --- a/util/mcgg/mcgg.h +++ b/util/mcgg/mcgg.h @@ -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 -- 2.34.1