IR codes are now owned by mcgg; ir terminals are inserted into the table during

compilation (so you can refer to them).
This commit is contained in:
David Given 2016-09-24 18:31:35 +02:00
parent 1516657907
commit 2acc4ed29d
10 changed files with 244 additions and 144 deletions

View file

@ -1,17 +1,5 @@
include("util/mcgg/build.lua") 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 { mcgg {
name = "mcgg_c", name = "mcgg_c",
srcs = { "./table" } srcs = { "./table" }
@ -22,10 +10,9 @@ cprogram {
srcs = { srcs = {
"./*.c", "./*.c",
"+mcgg_c", "+mcgg_c",
matching(filenamesof("+ircodes"), "%.c$")
}, },
deps = { deps = {
"+ircodes", "util/mcgg+lib",
"h+emheaders", "h+emheaders",
"modules+headers", "modules+headers",
"modules/src/alloc+lib", "modules/src/alloc+lib",

View file

@ -1,71 +0,0 @@
# 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

View file

@ -1,36 +0,0 @@
#!/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

View file

@ -31,17 +31,17 @@ static NODEPTR_TYPE tree(int op, NODEPTR_TYPE l, NODEPTR_TYPE r) {
int main(void) { int main(void) {
NODEPTR_TYPE p; NODEPTR_TYPE p;
p = tree(STORE, p = tree(STORE4,
tree(ADD, tree(ADD4,
tree(LABEL, 0, 0), tree(LABEL4, 0, 0),
tree(CONST, 0, 0) tree(CONST4, 0, 0)
), ),
tree(ADD, tree(ADD4,
tree(LOAD, tree(LOAD4,
tree(LABEL, 0, 0), tree(LABEL4, 0, 0),
0 0
), ),
tree(CONST, 0, 0) tree(CONST4, 0, 0)
) )
); );
burm_label(p); burm_label(p);

View file

@ -29,20 +29,19 @@ static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
} }
#endif #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 ins value:GPR
emit "str %value, %addr" emit "str %value, %addr"
cost 4; cost 4;
reg = LOAD(addr:address) reg = LOAD4(addr:address)
outs dest:ANY outs dest:ANY
emit "ld %dest, %addr" emit "ld %dest, %addr"
cost 4; cost 4;
address = ADD(addr:reg, offset:CONST) address = ADD4(addr:reg, offset:CONST)
ins addr:GPR ins addr:GPR
fragment "[%addr, #%offset.ivalue]"; fragment "[%addr, #%offset.ivalue]";
@ -52,19 +51,19 @@ static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
stm = reg; stm = reg;
reg = ADD(left:reg, right:aluparam) reg = ADD4(left:reg, right:aluparam)
ins left:GPR, right:GPR ins left:GPR, right:GPR
outs out:GPR outs out:GPR
emit "add %out, %left, %right" emit "add %out, %left, %right"
cost 4; cost 4;
reg = ADD(left:aluparam, right:reg) reg = ADD4(left:aluparam, right:reg)
ins left:GPR, right:GPR ins left:GPR, right:GPR
outs out:GPR outs out:GPR
emit "add %out, %right, %left" emit "add %out, %right, %left"
cost 4; cost 4;
aluparam = value:CONST aluparam = value:CONST4
when { return false; } when { return false; }
fragment "#%value.ivalue"; fragment "#%value.ivalue";
@ -75,12 +74,12 @@ static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
emit "mov %out, %value" emit "mov %out, %value"
cost 4; cost 4;
reg = value:LABEL reg = value:LABEL4
outs out:GPR outs out:GPR
emit "adr %out, #value.lvalue" emit "adr %out, #value.lvalue"
cost 4; cost 4;
reg = value:CONST reg = value:CONST4
outs out:GPR outs out:GPR
emit "ldr %out, #value.lvalue" emit "ldr %out, #value.lvalue"
cost 4; cost 4;

View file

@ -10,6 +10,28 @@ yacc {
srcs = { "./*.y" }, 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 { cprogram {
name = "mcgg", name = "mcgg",
srcs = { srcs = {
@ -19,6 +41,7 @@ cprogram {
}, },
deps = { deps = {
"./*.h", "./*.h",
"+lib",
"+yacc" "+yacc"
} }
} }
@ -51,7 +74,7 @@ definerule("mcgg",
cpptable cpptable
}, },
commands = { commands = {
"%{ins[1]} < %{ins[2]} > %{outs}", "%{ins[1]} -i %{ins[2]} -o %{outs}",
} }
} }
end end

View file

@ -6,7 +6,9 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <errno.h>
#include "iburg.h" #include "iburg.h"
#include "ircodes.h"
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id$";
@ -23,6 +25,7 @@ static int nrules;
static void print(char* fmt, ...); static void print(char* fmt, ...);
static void ckreach(Nonterm p); static void ckreach(Nonterm p);
static void registerterminals(void);
static void emitclosure(Nonterm nts); static void emitclosure(Nonterm nts);
static void emitcost(Tree t, char* v); static void emitcost(Tree t, char* v);
static void emitcostcalc(Rule r); static void emitcostcalc(Rule r);
@ -52,9 +55,12 @@ int main(int argc, char* argv[])
yydebug = 1; yydebug = 1;
#endif #endif
infp = stdin;
outfp = stdout;
for (;;) for (;;)
{ {
int opt = getopt(argc, argv, "p:"); int opt = getopt(argc, argv, "p:i:o:");
if (opt == -1) if (opt == -1)
break; break;
@ -64,16 +70,32 @@ int main(int argc, char* argv[])
prefix = optarg; prefix = optarg;
break; 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: default:
yyerror("usage: %s [-p prefix] < input > output\n", argv[0]); yyerror("usage: %s [-p prefix] < input > output\n", argv[0]);
exit(1); exit(1);
} }
} }
infp = stdin;
outfp = stdout;
emitheader(); emitheader();
registerterminals();
yyin = infp; yyin = infp;
yyparse(); yyparse();
@ -126,6 +148,32 @@ char* stringf(char* fmt, ...)
return p; 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 struct entry
{ {
union union
@ -196,10 +244,14 @@ Nonterm nonterm(const char* id)
/* term - create a new terminal id with external symbol number esn */ /* term - create a new terminal id with external symbol number esn */
Term term(const char* id, int esn) Term term(const char* id, int esn)
{ {
Term p = lookup(id), * q = &terms; Term p = lookup(id);
Term* q = &terms;
if (p) if (p)
{
yyerror("redefinition of terminal `%s'\n", id); yyerror("redefinition of terminal `%s'\n", id);
exit(1);
}
else else
p = install(id); p = install(id);
p->kind = TERM; p->kind = TERM;

View file

@ -86,4 +86,15 @@ extern int yylineno;
extern void printlineno(void); 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 #endif

74
util/mcgg/ir.dat Normal file
View file

@ -0,0 +1,74 @@
# 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

61
util/mcgg/ircodes.sh Executable file
View file

@ -0,0 +1,61 @@
#!/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