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:
parent
1516657907
commit
2acc4ed29d
|
@ -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",
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
74
util/mcgg/ir.dat
Normal 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
61
util/mcgg/ircodes.sh
Executable 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
|
||||||
|
|
Loading…
Reference in a new issue