diff --git a/mach/proto/mcg/build.lua b/mach/proto/mcg/build.lua index d1b2a3f49..246a11ee3 100644 --- a/mach/proto/mcg/build.lua +++ b/mach/proto/mcg/build.lua @@ -1,3 +1,5 @@ +include("util/mcgg/build.lua") + normalrule { name = "ircodes", outleaves = { "ircodes.h", "ircodes.c" }, @@ -10,10 +12,16 @@ normalrule { } } +mcgg { + name = "mcgg_c", + srcs = { "./table" } +} + cprogram { name = "mcg", srcs = { "./*.c", + "+mcgg_c", matching(filenamesof("+ircodes"), "%.c$") }, deps = { @@ -28,7 +36,6 @@ cprogram { "modules/src/string+lib", "modules/src/system+lib", "./*.h", - "util/mcgg+mcgg", }, vars = { ["+cflags"] = { diff --git a/util/mcgg/mcgg_generated_footer.h b/mach/proto/mcg/mcgg_generated_footer.h similarity index 100% rename from util/mcgg/mcgg_generated_footer.h rename to mach/proto/mcg/mcgg_generated_footer.h diff --git a/mach/proto/mcg/mcgg_generated_header.h b/mach/proto/mcg/mcgg_generated_header.h new file mode 100644 index 000000000..2545e8af3 --- /dev/null +++ b/mach/proto/mcg/mcgg_generated_header.h @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include + +#define TRACE + +#define STATE_TYPE void* +typedef struct tree { + int op; + struct tree *kids[2]; + STATE_TYPE state_label; +} *NODEPTR_TYPE; +#define OP_LABEL(p) ((p)->op) +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define STATE_LABEL(p) ((p)->state_label) +#define PANIC printf + +static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) { +#ifdef TRACE + extern const char *burm_string[]; + + fprintf(stderr, "0x%p matched %s with cost %d vs. %d\n", p, + burm_string[eruleno], cost, bestcost); +#endif +} + +#define burm_assert(b, s) assert(b && s) + diff --git a/mach/proto/mcg/table b/mach/proto/mcg/table new file mode 100644 index 000000000..f9a51c904 --- /dev/null +++ b/mach/proto/mcg/table @@ -0,0 +1,86 @@ +%{ +#if 0 +#include +#include +#include +#include + +#define TRACE + +#define STATE_TYPE void* +typedef struct tree { + int op; + struct tree *kids[2]; + STATE_TYPE state_label; +} *NODEPTR_TYPE; +#define OP_LABEL(p) ((p)->op) +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define STATE_LABEL(p) ((p)->state_label) +#define PANIC printf + +static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) { +#ifdef TRACE + extern const char *burm_string[]; + + fprintf(stderr, "0x%p matched %s with cost %d vs. %d\n", p, + burm_string[eruleno], cost, bestcost); +#endif +} +#endif +%} +%term LOAD STORE LABEL CONST ADD FOO BAR BAZ BOO; +%% + + stm = STORE(addr:address, value:reg) + ins value:GPR + emit "str %value, %addr" + cost 4; + + reg = LOAD(addr:address) + outs dest:ANY + emit "ld %dest, %addr" + cost 4; + + address = ADD(addr:reg, offset:CONST) + ins addr:GPR + fragment "[%addr, #%offset.ivalue]"; + + address = addr:reg + ins addr:GPR + fragment "[%addr]"; + + stm = reg; + + reg = ADD(left:reg, right:aluparam) + ins left:GPR, right:GPR + outs out:GPR + emit "add %out, %left, %right" + cost 4; + + reg = ADD(left:aluparam, right:reg) + ins left:GPR, right:GPR + outs out:GPR + emit "add %out, %right, %left" + cost 4; + + aluparam = value:CONST + when { return false; } + fragment "#%value.ivalue"; + + aluparam = reg; + + reg = value:aluparam + outs out:GPR + emit "mov %out, %value" + cost 4; + + reg = value:LABEL + outs out:GPR + emit "adr %out, #value.lvalue" + cost 4; + + reg = value:CONST + outs out:GPR + emit "ldr %out, #value.lvalue" + cost 4; diff --git a/util/mcgg/build.lua b/util/mcgg/build.lua index d0022baa9..a7d3cfde3 100644 --- a/util/mcgg/build.lua +++ b/util/mcgg/build.lua @@ -22,4 +22,38 @@ cprogram { "+yacc" } } + +definerule("mcgg", + { + srcs = { type="targets" } + }, + function(e) + -- Remember this is executed from the caller's directory; local + -- target names will resolve there + if (#e.srcs ~= 1) then + 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, + outleaves = { + "tables.c", + }, + ins = { + "util/mcgg+mcgg", + cpptable + }, + commands = { + "%{ins[1]} < %{ins[2]} > %{outs}", + } + } + end +) diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 8f305e751..05dd6c4ed 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -73,6 +73,8 @@ int main(int argc, char* argv[]) infp = stdin; outfp = stdout; + emitheader(); + yyin = infp; yyparse(); @@ -81,7 +83,7 @@ int main(int argc, char* argv[]) for (p = nts; p; p = p->link) if (!p->reached) yyerror("can't reach non-terminal `%s'\n", p->name); - emitheader(); + emitdefs(nts, ntnumber); emitstruct(nts, ntnumber); emitnts(rules, nrules); @@ -524,10 +526,7 @@ static void emitfuncs(void) /* emitheader - emit initial definitions */ static void emitheader(void) { - print("#include \n#include \n"); - print("#ifndef STATE_TYPE\n#define STATE_TYPE int\n#endif\n"); - print("#ifndef ALLOC\n#define ALLOC(n) malloc(n)\n#endif\n" - "#ifndef %Passert\n#define %Passert(x,y) if (!(x)) { y; abort(); }\n#endif\n\n"); + print("#include \"mcgg_generated_header.h\"\n"); if (Tflag) print("static NODEPTR_TYPE %Pnp;\n\n"); } @@ -752,8 +751,7 @@ static void emitstate(Term terms, Nonterm start, int ntnumber) "%1struct %Pstate* r = (struct %Pstate *)right;\n" "\n" "%1assert(sizeof (STATE_TYPE) >= sizeof (void *));\n%1"); - print("%1p = ALLOC(sizeof *p);\n" - "%1%Passert(p, PANIC(\"ALLOC returned NULL in %Pstate\\n\"));\n" + print("%1p = malloc(sizeof *p);\n" "%1p->op = op;\n" "%1p->left = l;\n" "%1p->right = r;\n"