Collapse several rule arrays into one; actually generate the array properly.
authorDavid Given <dg@cowlark.com>
Sun, 25 Sep 2016 15:14:54 +0000 (17:14 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 25 Sep 2016 15:14:54 +0000 (17:14 +0200)
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/table
util/mcgg/iburg.c
util/mcgg/mcgg.h

index e54b6ea..bfdaa77 100644 (file)
@@ -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)
index efaffdc..9146f63 100644 (file)
@@ -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;
index c4189f5..399ebdd 100644 (file)
@@ -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");
 }
 
index 1a1be1b..1279ee0 100644 (file)
@@ -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