compilation (so you can refer to them).
include("util/mcgg/build.lua")
-normalrule {
- name = "ircodes",
- outleaves = { "ircodes.h", "ircodes.c" },
- ins = {
- "./ircodes.sh",
- "./ir.dat"
- },
- commands = {
- "%{ins[1]} %{ins[2]} %{outs[1]} %{outs[2]}"
- }
-}
-
mcgg {
name = "mcgg_c",
srcs = { "./table" }
srcs = {
"./*.c",
"+mcgg_c",
- matching(filenamesof("+ircodes"), "%.c$")
},
deps = {
- "+ircodes",
+ "util/mcgg+lib",
"h+emheaders",
"modules+headers",
"modules/src/alloc+lib",
+++ /dev/null
-# Simple terminals
-CONST
-REG
-LABEL
-BLOCK
-PAIR
-ANY
-LOCAL
-PHI
-
-# Magic stack operations
-PUSH
-POP
-SET
-
-# Memory operations
-LOAD
-STORE
-
-# Arithemetic operations
-ADD
-SUB
-MUL
-DIV
-MOD
-NEG
-
-ADDF
-SUBF
-MULF
-DIVF
-NEGF
-
-AND
-OR
-EOR
-NOT
-
-# Conversions
-CII1
-CII2
-CII4
-CII8
-
-CIU1
-CIU2
-CIU4
-CIU8
-
-# Tristate comparisons
-COMPARES
-COMPAREU
-
-# Boolean comparisons
-IFEQ
-IFLT
-IFLE
-
-# Procedures
-CALL
-
-# Flow control --- these never return
-JUMP
-CJUMP
-RET
-
-# Special
-STACKADJUST
-GETRET
-SETRET
-
+++ /dev/null
-#!/bin/sh
-
-in=$1
-header=$2
-source=$3
-
-awk -f - $in >$header << "EOF"
- BEGIN {
- print "enum ir_opcode {"
- }
-
- /^[^#]+/ {
- print "\tIR_" $1 ","
- }
-
- END {
- print "};"
- }
-EOF
-
-awk -f - $in >$source << "EOF"
- BEGIN {
- print "#include \"mcg.h\""
- print "#include \"ir.h\""
- print "const char* ir_names[] = {"
- }
-
- /^[^#]+/ {
- printf("\t\"%s\",\n", $1)
- }
-
- END {
- print "};"
- }
-EOF
-
int main(void) {
NODEPTR_TYPE p;
- p = tree(STORE,
- tree(ADD,
- tree(LABEL, 0, 0),
- tree(CONST, 0, 0)
+ p = tree(STORE4,
+ tree(ADD4,
+ tree(LABEL4, 0, 0),
+ tree(CONST4, 0, 0)
),
- tree(ADD,
- tree(LOAD,
- tree(LABEL, 0, 0),
+ tree(ADD4,
+ tree(LOAD4,
+ tree(LABEL4, 0, 0),
0
),
- tree(CONST, 0, 0)
+ tree(CONST4, 0, 0)
)
);
burm_label(p);
}
#endif
%}
-%term LOAD STORE LABEL CONST ADD FOO BAR BAZ BOO;
%%
- stm = STORE(addr:address, value:reg)
+ stm = STORE4(addr:address, value:reg)
ins value:GPR
emit "str %value, %addr"
cost 4;
- reg = LOAD(addr:address)
+ reg = LOAD4(addr:address)
outs dest:ANY
emit "ld %dest, %addr"
cost 4;
- address = ADD(addr:reg, offset:CONST)
+ address = ADD4(addr:reg, offset:CONST)
ins addr:GPR
fragment "[%addr, #%offset.ivalue]";
stm = reg;
- reg = ADD(left:reg, right:aluparam)
+ reg = ADD4(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)
+ reg = ADD4(left:aluparam, right:reg)
ins left:GPR, right:GPR
outs out:GPR
emit "add %out, %right, %left"
cost 4;
- aluparam = value:CONST
+ aluparam = value:CONST4
when { return false; }
fragment "#%value.ivalue";
emit "mov %out, %value"
cost 4;
- reg = value:LABEL
+ reg = value:LABEL4
outs out:GPR
emit "adr %out, #value.lvalue"
cost 4;
- reg = value:CONST
+ reg = value:CONST4
outs out:GPR
emit "ldr %out, #value.lvalue"
cost 4;
srcs = { "./*.y" },
}
+normalrule {
+ name = "ircodes",
+ outleaves = { "ircodes.h", "ircodes.c" },
+ ins = {
+ "./ircodes.sh",
+ "./ir.dat"
+ },
+ commands = {
+ "%{ins[1]} %{ins[2]} %{outs[1]} %{outs[2]}"
+ }
+}
+
+clibrary {
+ name = "lib",
+ srcs = {
+ matching(filenamesof("+ircodes"), "%.c$")
+ },
+ hdrs = {
+ matching(filenamesof("+ircodes"), "%.h$")
+ }
+}
+
cprogram {
name = "mcgg",
srcs = {
},
deps = {
"./*.h",
+ "+lib",
"+yacc"
}
}
cpptable
},
commands = {
- "%{ins[1]} < %{ins[2]} > %{outs}",
+ "%{ins[1]} -i %{ins[2]} -o %{outs}",
}
}
end
#include <ctype.h>
#include <string.h>
#include <limits.h>
+#include <errno.h>
#include "iburg.h"
+#include "ircodes.h"
static char rcsid[] = "$Id$";
static void print(char* fmt, ...);
static void ckreach(Nonterm p);
+static void registerterminals(void);
static void emitclosure(Nonterm nts);
static void emitcost(Tree t, char* v);
static void emitcostcalc(Rule r);
yydebug = 1;
#endif
+ infp = stdin;
+ outfp = stdout;
+
for (;;)
{
- int opt = getopt(argc, argv, "p:");
+ int opt = getopt(argc, argv, "p:i:o:");
if (opt == -1)
break;
prefix = optarg;
break;
+ case 'i':
+ infp = fopen(optarg, "r");
+ if (!infp)
+ {
+ yyerror("cannot open input file: %s\n", strerror(errno));
+ exit(1);
+ }
+ break;
+
+ case 'o':
+ outfp = fopen(optarg, "w");
+ if (!outfp)
+ {
+ yyerror("cannot open output file: %s\n", strerror(errno));
+ exit(1);
+ }
+ break;
+
default:
yyerror("usage: %s [-p prefix] < input > output\n", argv[0]);
exit(1);
}
}
- infp = stdin;
- outfp = stdout;
-
emitheader();
+ registerterminals();
yyin = infp;
yyparse();
return p;
}
+static void registerterminal(const char* name, int iropcode, int size)
+{
+ const char* s = (size == 0) ? name : stringf("%s%d", name, size);
+ int esn = ir_to_esn(iropcode, size);
+
+ term(s, esn);
+}
+
+static void registerterminals(void)
+{
+ int i;
+
+ for (i=0; i<IR__COUNT; i++)
+ {
+ if (ir_flags[i] & IRF_SIZED)
+ {
+ registerterminal(ir_names[i], i, 1);
+ registerterminal(ir_names[i], i, 2);
+ registerterminal(ir_names[i], i, 4);
+ registerterminal(ir_names[i], i, 8);
+ }
+ else
+ registerterminal(ir_names[i], i, 0);
+ }
+}
+
struct entry
{
union
/* term - create a new terminal id with external symbol number esn */
Term term(const char* id, int esn)
{
- Term p = lookup(id), * q = &terms;
+ Term p = lookup(id);
+ Term* q = &terms;
if (p)
+ {
yyerror("redefinition of terminal `%s'\n", id);
+ exit(1);
+ }
else
p = install(id);
p->kind = TERM;
extern void printlineno(void);
+/* Excruciating macro which packs ir opcodes and sizes into an int for iburg's benefit.
+ *
+ * Sizes are mapped as: 0=1, 1=1, 2=2, 4=3, 8=4.
+ */
+#define ir_to_esn(iropcode, size) \
+ ((iropcode)*4 + \
+ (((size) == 4) ? 2 : \
+ ((size) == 8) ? 3 : \
+ ((size) == 0) ? 0 : \
+ (size-1)))
+
#endif
--- /dev/null
+# Flags:
+# S: has size (use in CONST1, CONST2, CONST4, CONST8 forms)
+# V: has no size (use in JUMP, CJUMP, RET forms)
+
+# Simple terminals
+S CONST
+S REG
+S LABEL
+S BLOCK
+S PAIR
+S ANY
+S LOCAL
+S PHI
+
+# Magic stack operations
+S PUSH
+S POP
+
+# Memory operations
+S LOAD
+S STORE
+
+# Arithemetic operations
+S ADD
+S SUB
+S MUL
+S DIV
+S MOD
+S NEG
+
+S ADDF
+S SUBF
+S MULF
+S DIVF
+S NEGF
+
+S AND
+S OR
+S EOR
+S NOT
+
+# Conversions
+S CII1
+S CII2
+S CII4
+S CII8
+
+S CIU1
+S CIU2
+S CIU4
+S CIU8
+
+# Tristate comparisons
+S COMPARES
+S COMPAREU
+
+# Boolean comparisons
+S IFEQ
+S IFLT
+S IFLE
+
+# Procedures
+V CALL
+
+# Flow control --- these never return
+V JUMP
+V CJUMP
+V RET
+
+# Special
+S STACKADJUST
+S GETRET
+S SETRET
+
--- /dev/null
+#!/bin/sh
+
+in=$1
+header=$2
+source=$3
+
+awk -f - $in >$header << "EOF"
+ BEGIN {
+ print "enum ir_opcode {"
+ }
+
+ /^ *[^# ]+/ {
+ print "\tIR_" $2 ","
+ }
+
+ END {
+ print "\tIR__COUNT"
+ print "};"
+ print ""
+ print "enum {"
+ print "\tIRF_SIZED = 1"
+ print "};"
+ print ""
+ print "extern const char* ir_names[IR__COUNT];"
+ print "extern const char ir_flags[IR__COUNT];"
+ }
+EOF
+
+awk -f - $in >$source << "EOF"
+ BEGIN {
+ print "#include \"ircodes.h\""
+ print "const char* ir_names[IR__COUNT] = {"
+ }
+
+ /^ *[^# ]+/ {
+ printf("\t\"%s\",\n", $2)
+ }
+
+ END {
+ print "};"
+ }
+EOF
+
+awk -f - $in >>$source << "EOF"
+ BEGIN {
+ print ""
+ print "const char ir_flags[IR__COUNT] = {"
+ }
+
+ /^ *[^# ]+/ {
+ if ($1 == "S")
+ print("\tIRF_SIZED,")
+ else
+ print("\t0,")
+ }
+
+ END {
+ print "};"
+ }
+EOF
+