Rethink the way patterns are mapped to rules; generate emitters (probably
authorDavid Given <dg@cowlark.com>
Sun, 25 Sep 2016 09:49:51 +0000 (11:49 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 25 Sep 2016 09:49:51 +0000 (11:49 +0200)
badly).

mach/proto/mcg/table
util/mcgg/build.lua
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/mcgg.h
util/mcgg/scan.l

index b32d432..efaffdc 100644 (file)
@@ -14,8 +14,7 @@ PATTERNS
                cost 4;
 
        reg = POP4
-               outs out:ANY
-               emit "pop %out"
+               emit "pop %reg"
                cost 4;
 
        RET
@@ -29,31 +28,26 @@ PATTERNS
 /* Memory operations */
 
        STORE4(addr:address, value:reg)
-               ins value:GPR
                emit "str %value, %addr"
                cost 4;
 
        reg = LOAD4(addr:address)
-               outs dest:ANY
-               emit "ldr %dest, %addr"
+               emit "ldr %reg, %addr"
                cost 4;
 
        reg = LOAD1(addr:address)
-               outs dest:ANY
-               emit "ldrb %dest, %addr"
+               emit "ldrb %reg, %addr"
                cost 4;
 
        reg = CIU14(LOAD1(addr:address))
-               outs dest:ANY
-               emit "ldrb %dest, %addr"
+               emit "ldrb %reg, %addr"
                cost 4;
 
 
 /* Locals */
 
        reg = in:LOCAL4
-               outs out:GPR
-               emit "add %out, fp, #%in"
+               emit "add %reg, fp, #%in"
                cost 4;
 
        address = in:LOCAL4
@@ -63,11 +57,9 @@ PATTERNS
 /* Memory addressing modes */
 
        address = ADD4(addr:reg, offset:CONST)
-               ins addr:GPR
                fragment "[%addr, #%offset]";
 
        address = addr:reg
-               ins addr:GPR
                fragment "[%addr]";
 
 
@@ -85,43 +77,37 @@ PATTERNS
 
 /* Comparisons */
 
-       tristate = COMPARES4(val1:reg, val2:aluparam)
+       tristate = COMPARES4(left:reg, right:aluparam)
                outs CC
-               emit "cmp %val1, %val2"
+               emit "cmp %left, %right"
                cost 4;
 
        reg = tristate
-               emit "mov %out, #0"
-               emit "movlt %out, #-1"
-               emit "movgt %out, #1"
+               emit "mov %reg, #0"
+               emit "movlt %reg, #-1"
+               emit "movgt %reg, #1"
                cost 12;
 
 
 /* Conversions */
 
        reg = CII14(CIU41(value:reg))
-               outs out:GPR
-               emit "sxtb %out, %value"
+               emit "sxtb %reg, %value"
                cost 4;
 
        reg = CIU41(in:reg)
-               outs out:GPR
-               emit "and %out, %in, #0xff"
+               emit "and %reg, %in, #0xff"
                cost 4;
 
 
 /* ALU operations */
 
        reg = ADD4(left:reg, right:aluparam)
-               ins left:GPR, right:GPR
-               outs out:GPR
-               emit "add %out, %left, %right"
+               emit "add %reg, %left, %right"
                cost 4;
 
        reg = ADD4(left:aluparam, right:reg)
-               ins left:GPR, right:GPR
-               outs out:GPR
-               emit "add %out, %right, %left"
+               emit "add %reg, %right, %left"
                cost 4;
 
        aluparam = value:CONST4
@@ -130,21 +116,17 @@ PATTERNS
        aluparam = reg;
 
        reg = value:aluparam
-               outs out:GPR
-               emit "mov %out, %value"
+               emit "mov %reg, %value"
                cost 4;
 
        reg = value:LABEL4
-               outs out:GPR
-               emit "adr %out, %value"
+               emit "adr %reg, %value"
                cost 4;
 
        reg = value:BLOCK4
-               outs out:GPR
-               emit "adr %out, %value"
+               emit "adr %reg, %value"
                cost 4;
 
        reg = value:CONST4
-               outs out:GPR
-               emit "ldr %out, #value"
+               emit "ldr %reg, #value"
                cost 4;
index 0485197..ee230d7 100644 (file)
@@ -58,12 +58,6 @@ definerule("mcgg",
                        error("you must supply exactly one input file")
                end
 
-               local cpptable = cppfile {
-                       name = e.name.."/cpptable",
-                       outleaf = "cpptable",
-                       srcs = e.srcs
-               }
-
                return normalrule {
                        name = e.name,
                        cwd = e.cwd,
@@ -72,7 +66,7 @@ definerule("mcgg",
                        },
                        ins = {
                                "util/mcgg+mcgg",
-                               cpptable
+                               e.srcs[1]
                        },
                        commands = {
                                "%{ins[1]} -i %{ins[2]} -o %{outs}",
index cbbfab5..52df9cc 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <ctype.h>
 #include <string.h>
 #include <limits.h>
@@ -40,6 +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 emitstate(Term terms, Nonterm start, int ntnumber);
 static void emitstring(Rule rules);
 static void emitstruct(Nonterm nts, int ntnumber);
@@ -133,6 +135,7 @@ int main(int argc, char* argv[])
        emitrule(nts);
        emitclosure(nts);
        emitpredicatedefinitions(rules);
+       emitemitters(rules);
        if (start)
                emitstate(terms, start, ntnumber);
        print("#ifdef STATE_LABEL\n");
@@ -334,6 +337,7 @@ Rule rule(char* id, Tree pattern, int ern)
        Term p = pattern->op;
 
        nrules++;
+       r->lineno = yylineno;
        r->lhs = nonterm(id);
        r->packed = ++r->lhs->lhscount;
        for (q = &r->lhs->rules; *q; q = &(*q)->decode)
@@ -791,6 +795,7 @@ static void emitpredicatedefinitions(Rule r)
                Stringlist s = r->when;
                if (s)
                {
+                       print("/* %R */\n", r);
                        print("static int %Ppredicate_%d(NODEPTR_TYPE n) {\n", r->ern);
                        while (s)
                        {
@@ -803,6 +808,115 @@ static void emitpredicatedefinitions(Rule r)
        }
 }
 
+static void emittreefetchers(uint32_t path, Tree tree)
+{
+       if (tree->label)
+       {
+               int i = 0;
+               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;
+                       }
+                       p /= 3;
+                       i++;
+               }
+
+               print("node");
+
+               while (i > 0)
+               {
+                       print(")");
+                       i--;
+               }
+               
+               print(";\n");
+       }
+
+       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)
+{
+       Tree t;
+
+       if (root->label && (strcmp(root->label, name) == 0))
+               return root;
+
+       t = NULL;
+       if (root->left && !t)
+               t = find_label(root->left, name);
+       if (root->right && !t)
+               t = find_label(root->right, name);
+       return t;
+}
+
+/* emitemitters - emit the code generation routines */
+static void emitemitters(Rule rules)
+{
+       Rule r;
+
+       r = rules;
+       while (r)
+       {
+               Stringlist s = r->code;
+               if (s)
+               {
+                       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 (s)
+                       {
+                               if (s->payload[0] == '%')
+                               {
+                                       const char* label = s->payload + 1;
+                                       Tree t = find_label(r->pattern, label);
+                                       if (!t && (strcmp(label, r->lhs->name) != 0))
+                                       {
+                                               yylineno = r->lineno;
+                                               yyerror("label '%s' not found", label);
+                                               exit(1);
+                                       }
+                                       print("%1data->emit_ir(node_%s);\n", label);
+                               }
+                               else
+                                       print("%1data->emit_string(\"%s\");\n", s->payload);
+
+                               s = s->next;
+                       }
+
+                       print("}\n\n");
+               }
+
+               r = r->link;
+       }
+
+       r = rules;
+       print("%Pemitter_t* const %Pemitters[] = {\n");
+       while (r)
+       {
+               Stringlist s = r->code;
+               print("%1");
+               if (s)
+                       print("&%Pemitter_%d,", r->ern);
+               else
+                       print("NULL,");
+               print(" /* %R */\n", r);
+
+               r = r->link;
+       }
+       print("};\n\n");
+}
+
 /* emitcost - emit a cost calculation via a predicate */
 static void emitcostcalc(Rule r)
 {
index 361cdba..0a6c90d 100644 (file)
@@ -58,6 +58,7 @@ struct rule
 { /* rules: */
        Nonterm lhs;     /* lefthand side non-terminal */
        Tree pattern;    /* rule pattern */
+       int lineno;      /* line number where allocated */
        int ern;         /* external rule number */
        int packed;      /* packed external rule number */
        int cost;        /* associated cost */
index 297be18..10d8f51 100644 (file)
@@ -25,6 +25,16 @@ 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);
 
+struct burm_emitter_data
+{
+       void* user;
+    void (*emit_string)(const char* data);
+    void (*emit_ir)(struct ir* ir);
+};
+
+typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data);
+extern burm_emitter_t* const burm_emitters[];
+
 #endif
 
 /* vim: set sw=4 ts=4 expandtab : */
index 941830c..479a115 100644 (file)
@@ -14,7 +14,7 @@ static int braces = 0;
 
 %x CSTRING
 %x QSTRING
-%x ECHO
+%x COMMENT
 
 %%
 
@@ -50,7 +50,7 @@ static int braces = 0;
 <INITIAL>"\""               BEGIN(QSTRING);
 <QSTRING>"\""               BEGIN(INITIAL);
 
-<QSTRING>%[a-zA-Z_]+        {
+<QSTRING>%[a-zA-Z_][a-zA_Z_0-9]+ {
                                 yylval.string = strdup(yytext);
                                 return QFRAGMENT;
                             }
@@ -60,6 +60,11 @@ static int braces = 0;
                                 return QFRAGMENT;
                             }
 
+<INITIAL>"/*"               BEGIN(COMMENT);
+<COMMENT>"*/"               BEGIN(INITIAL);
+<COMMENT>[^*]*              ;
+<COMMENT>"*"                ;
+
 "%%"                        return PPERCENT;
 "%term"                                                return TERMINAL;
 "%start"                                       return START;
@@ -72,6 +77,8 @@ static int braces = 0;
 "fragment"                  return FRAGMENT;
 "cost"                      return COST;
 
+"//"[^\n]*\n                ;
+
 [A-Za-z_][A-Za-z0-9_]*      { yylval.string = strdup(yytext); return ID; }
 [0-9]+                      { yylval.n = atoi(yytext); return INT; }
 [ \t\r\n]*                  ;