Crudely bolt on mcgg to mcg itself.

This commit is contained in:
David Given 2016-09-24 17:20:40 +02:00
parent 13132128a1
commit 1516657907
6 changed files with 165 additions and 8 deletions

View file

@ -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"] = {

View file

@ -0,0 +1,32 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#include <stdlib.h>
#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)

86
mach/proto/mcg/table Normal file
View file

@ -0,0 +1,86 @@
%{
#if 0
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#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;

View file

@ -23,3 +23,37 @@ cprogram {
}
}
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
)

View file

@ -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 <limits.h>\n#include <stdlib.h>\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"