Tracing cleanup. Simplified the IR code. Some more opcodes.
This commit is contained in:
parent
4546dd5f22
commit
6a74cb2e11
11 changed files with 221 additions and 114 deletions
|
@ -39,4 +39,8 @@ void bb_alias(struct basicblock* block, const char* name)
|
||||||
p->block = block;
|
p->block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bb_print(char k, struct basicblock* block)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* vim: set sw=4 ts=4 expandtab : */
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -24,7 +24,8 @@ cprogram {
|
||||||
"modules/src/em_code+lib_k",
|
"modules/src/em_code+lib_k",
|
||||||
"modules/src/em_data+lib",
|
"modules/src/em_data+lib",
|
||||||
"modules/src/idf+lib",
|
"modules/src/idf+lib",
|
||||||
"modules/src/read_em+lib_kv",
|
"modules/src/read_em+lib_ev",
|
||||||
|
"modules/src/string+lib",
|
||||||
"modules/src/system+lib",
|
"modules/src/system+lib",
|
||||||
"./*.h",
|
"./*.h",
|
||||||
"util/mcgg+mcgg",
|
"util/mcgg+mcgg",
|
||||||
|
|
41
mach/proto/mcg/compile.c
Normal file
41
mach/proto/mcg/compile.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include "mcg.h"
|
||||||
|
|
||||||
|
static void print_blocks(char k, struct procedure* proc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tracef(k, "%c: procedure %s\n", k, proc->name);
|
||||||
|
for (int i=0; i<proc->blocks_count; i++)
|
||||||
|
{
|
||||||
|
struct basicblock* bb = proc->blocks[i];
|
||||||
|
int j;
|
||||||
|
|
||||||
|
tracef(k, "%c: block %s\n", k, bb->name);
|
||||||
|
|
||||||
|
for (int j=0; j<bb->inblocks_count; j++)
|
||||||
|
{
|
||||||
|
struct basicblock* obb = bb->inblocks[j];
|
||||||
|
tracef(k, "%c: %s ->\n", k, obb->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j=0; j<bb->irs_count; j++)
|
||||||
|
ir_print(k, bb->irs[j]);
|
||||||
|
|
||||||
|
for (int j=0; j<bb->outblocks_count; j++)
|
||||||
|
{
|
||||||
|
struct basicblock* obb = bb->outblocks[j];
|
||||||
|
tracef(k, "%c: -> %s\n", k, obb->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compile(struct procedure* proc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
print_blocks('1', proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -35,18 +35,16 @@ struct ir* new_labelir(const char* label)
|
||||||
return ir;
|
return ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ir* new_wordir(arith value)
|
struct ir* new_constir(int size, arith value)
|
||||||
{
|
{
|
||||||
struct ir* ir = new_ir0(IR_ICONST, EM_wordsize);
|
struct ir* ir = new_ir0(IR_CONST, size);
|
||||||
ir->u.ivalue = value;
|
ir->u.ivalue = value;
|
||||||
return ir;
|
return ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ir* new_regir(int reg)
|
struct ir* new_wordir(arith value)
|
||||||
{
|
{
|
||||||
struct ir* ir = new_ir0(IR_REG, EM_pointersize);
|
return new_constir(EM_wordsize, value);
|
||||||
ir->u.rvalue = reg;
|
|
||||||
return ir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ir* new_bbir(struct basicblock* bb)
|
struct ir* new_bbir(struct basicblock* bb)
|
||||||
|
@ -61,51 +59,50 @@ struct ir* new_anyir(int size)
|
||||||
return new_ir0(IR_ANY, size);
|
return new_ir0(IR_ANY, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ir* new_phiir(int size)
|
struct ir* new_localir(int offset)
|
||||||
{
|
{
|
||||||
return new_ir0(IR_PHI, size);
|
struct ir* ir = new_ir0(IR_LOCAL, EM_pointersize);
|
||||||
|
ir->u.ivalue = offset;
|
||||||
|
return ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_print(const struct ir* ir)
|
void ir_print(char k, const struct ir* ir)
|
||||||
{
|
{
|
||||||
if (ir->left)
|
if (ir->left && !ir->left->is_sequence)
|
||||||
ir_print(ir->left);
|
ir_print(k, ir->left);
|
||||||
if (ir->right)
|
if (ir->right && !ir->right->is_sequence)
|
||||||
ir_print(ir->right);
|
ir_print(k, ir->right);
|
||||||
|
|
||||||
printf("\t; %c ",
|
tracef(k, "%c: %c ", k, ir->is_sequence ? 'S' : ' ');
|
||||||
ir->is_sequence ? 'S' : ' ');
|
tracef(k, "$%d = ", ir->id);
|
||||||
printf("$%d = ", ir->id);
|
tracef(k, "%s", ir_names[ir->opcode]);
|
||||||
printf("%s%d(",
|
if (ir->size)
|
||||||
ir_names[ir->opcode],
|
tracef(k, "%d", ir->size);
|
||||||
ir->size);
|
tracef(k, "(");
|
||||||
|
|
||||||
switch (ir->opcode)
|
switch (ir->opcode)
|
||||||
{
|
{
|
||||||
case IR_ICONST:
|
case IR_CONST:
|
||||||
printf("%d", ir->u.ivalue);
|
case IR_LOCAL:
|
||||||
|
tracef(k, "%d", ir->u.ivalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IR_LABEL:
|
case IR_LABEL:
|
||||||
printf("%s", ir->u.lvalue);
|
tracef(k, "%s", ir->u.lvalue);
|
||||||
break;
|
|
||||||
|
|
||||||
case IR_REG:
|
|
||||||
printf("%d", ir->u.rvalue);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IR_BLOCK:
|
case IR_BLOCK:
|
||||||
printf("%s", ir->u.bvalue->name);
|
tracef(k, "%s", ir->u.bvalue->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (ir->left)
|
if (ir->left)
|
||||||
printf("$%d", ir->left->id);
|
tracef(k, "$%d", ir->left->id);
|
||||||
if (ir->right)
|
if (ir->right)
|
||||||
printf(", $%d", ir->right->id);
|
tracef(k, ", $%d", ir->right->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(")\n");
|
tracef(k, ")\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set sw=4 ts=4 expandtab : */
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Simple terminals
|
# Simple terminals
|
||||||
ICONST
|
CONST
|
||||||
REG
|
REG
|
||||||
LABEL
|
LABEL
|
||||||
BLOCK
|
BLOCK
|
||||||
PAIR
|
PAIR
|
||||||
ANY
|
ANY
|
||||||
PHI
|
LOCAL
|
||||||
|
|
||||||
# Magic stack operations
|
# Magic stack operations
|
||||||
PUSH
|
PUSH
|
||||||
|
@ -22,11 +22,17 @@ MUL
|
||||||
DIV
|
DIV
|
||||||
MOD
|
MOD
|
||||||
NEG
|
NEG
|
||||||
NOT
|
|
||||||
|
ADDF
|
||||||
|
SUBF
|
||||||
|
MULF
|
||||||
|
DIVF
|
||||||
|
NEGF
|
||||||
|
|
||||||
AND
|
AND
|
||||||
OR
|
OR
|
||||||
EOR
|
EOR
|
||||||
|
NOT
|
||||||
|
|
||||||
# Conversions
|
# Conversions
|
||||||
CII1
|
CII1
|
||||||
|
@ -55,6 +61,7 @@ CJUMP
|
||||||
RET
|
RET
|
||||||
|
|
||||||
# Special
|
# Special
|
||||||
SETREG
|
STACKADJUST
|
||||||
GETREG
|
GETRET
|
||||||
|
SETRET
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef IR_H
|
#ifndef IR_H
|
||||||
#define IR_H
|
#define IR_H
|
||||||
|
|
||||||
#include "ircodes.h"
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
IRR_LB = -1,
|
IRR_LB = -1,
|
||||||
|
@ -11,6 +9,14 @@ enum
|
||||||
IRR_RR = -4,
|
IRR_RR = -4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IRS_1,
|
||||||
|
IRS_2,
|
||||||
|
IRS_4,
|
||||||
|
IRS_8
|
||||||
|
};
|
||||||
|
|
||||||
struct ir
|
struct ir
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
@ -23,9 +29,6 @@ struct ir
|
||||||
int rvalue;
|
int rvalue;
|
||||||
const char* lvalue;
|
const char* lvalue;
|
||||||
struct basicblock* bvalue;
|
struct basicblock* bvalue;
|
||||||
struct {
|
|
||||||
ARRAY(struct ir, srcs);
|
|
||||||
} phivalue;
|
|
||||||
} u;
|
} u;
|
||||||
bool is_sequence : 1;
|
bool is_sequence : 1;
|
||||||
};
|
};
|
||||||
|
@ -39,13 +42,15 @@ extern struct ir* new_ir2(int opcode, int size,
|
||||||
struct ir* c1, struct ir* c2);
|
struct ir* c1, struct ir* c2);
|
||||||
|
|
||||||
extern struct ir* new_labelir(const char* label);
|
extern struct ir* new_labelir(const char* label);
|
||||||
extern struct ir* new_regir(int reg);
|
|
||||||
extern struct ir* new_wordir(arith value);
|
extern struct ir* new_wordir(arith value);
|
||||||
|
extern struct ir* new_constir(int size, arith value);
|
||||||
extern struct ir* new_bbir(struct basicblock* bb);
|
extern struct ir* new_bbir(struct basicblock* bb);
|
||||||
extern struct ir* new_anyir(int size);
|
extern struct ir* new_anyir(int size);
|
||||||
extern struct ir* new_phiir(int size);
|
extern struct ir* new_localir(int offset);
|
||||||
|
|
||||||
extern void ir_print(const struct ir* ir);
|
extern void ir_print(char k, const struct ir* ir);
|
||||||
|
|
||||||
|
#include "ircodes.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,33 @@ in=$1
|
||||||
header=$2
|
header=$2
|
||||||
source=$3
|
source=$3
|
||||||
|
|
||||||
echo "enum {" > $header
|
awk -f - $in >$header << "EOF"
|
||||||
sed -n 's/^[A-Z].*$/IR_&,/p' < $in >> $header
|
BEGIN {
|
||||||
echo "};" >> $header
|
print "enum {"
|
||||||
|
}
|
||||||
|
|
||||||
echo "const char* ir_names[] = {" > $source
|
/^[^#]+/ {
|
||||||
sed -n 's/^[A-Z].*$/"&",/p' < $in >> $source
|
print "\tIR_" $1 ","
|
||||||
echo "};" >> $source
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,30 @@ const char* aprintf(const char* fmt, ...)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tracing(char k)
|
||||||
|
{
|
||||||
|
switch (k)
|
||||||
|
{
|
||||||
|
case 'E': return true;
|
||||||
|
case '0': return true;
|
||||||
|
case '1': return true;
|
||||||
|
case '2': return true;
|
||||||
|
default: return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tracef(char k, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (tracing(k))
|
||||||
|
{
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
symbol_init();
|
symbol_init();
|
||||||
|
|
|
@ -77,17 +77,18 @@ struct basicblock
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
ARRAY(struct insn, insns);
|
ARRAY(struct insn, insns);
|
||||||
|
ARRAY(struct ir, allirs);
|
||||||
ARRAY(struct ir, irs);
|
ARRAY(struct ir, irs);
|
||||||
ARRAY(struct basicblock, inblocks);
|
ARRAY(struct basicblock, inblocks);
|
||||||
ARRAY(struct basicblock, outblocks);
|
ARRAY(struct basicblock, outblocks);
|
||||||
ARRAY(struct ir, outs);
|
|
||||||
ARRAY(struct ir, ins);
|
|
||||||
bool is_root : 1;
|
bool is_root : 1;
|
||||||
bool is_terminated : 1;
|
bool is_terminated : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void fatal(const char* s, ...);
|
extern void fatal(const char* s, ...);
|
||||||
extern const char* aprintf(const char* fmt, ...);
|
extern const char* aprintf(const char* fmt, ...);
|
||||||
|
extern void tracef(char k, const char* fmt, ...);
|
||||||
|
extern bool tracing(char k);
|
||||||
|
|
||||||
extern void parse_em(void);
|
extern void parse_em(void);
|
||||||
|
|
||||||
|
@ -105,12 +106,15 @@ extern void data_bss(arith size, int init);
|
||||||
extern void bb_init(void);
|
extern void bb_init(void);
|
||||||
extern struct basicblock* bb_get(const char* name);
|
extern struct basicblock* bb_get(const char* name);
|
||||||
extern void bb_alias(struct basicblock* block, const char* name);
|
extern void bb_alias(struct basicblock* block, const char* name);
|
||||||
|
extern void bb_print(char k, struct basicblock* block);
|
||||||
|
|
||||||
extern void tb_filestart(void);
|
extern void tb_filestart(void);
|
||||||
extern void tb_fileend(void);
|
extern void tb_fileend(void);
|
||||||
extern void tb_procedure(struct procedure* proc);
|
extern void tb_procedure(struct procedure* proc);
|
||||||
extern void tb_regvar(arith offset, int size, int type, int priority);
|
extern void tb_regvar(arith offset, int size, int type, int priority);
|
||||||
|
|
||||||
|
extern void compile(struct procedure* proc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* vim: set sw=4 ts=4 expandtab : */
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -289,6 +289,7 @@ static void parse_pseu(void)
|
||||||
|
|
||||||
case ps_end: /* procedure end */
|
case ps_end: /* procedure end */
|
||||||
tb_procedure(current_proc);
|
tb_procedure(current_proc);
|
||||||
|
compile(current_proc);
|
||||||
|
|
||||||
current_proc = NULL;
|
current_proc = NULL;
|
||||||
code_bb = NULL;
|
code_bb = NULL;
|
||||||
|
|
|
@ -6,7 +6,7 @@ static struct basicblock* current_bb;
|
||||||
static int stackptr;
|
static int stackptr;
|
||||||
static struct ir* stack[64];
|
static struct ir* stack[64];
|
||||||
|
|
||||||
static struct ir* convert(struct ir* src, int destsize, int opcode);
|
static struct ir* convert(struct ir* src, int destsize, int opcodebase);
|
||||||
static struct ir* appendir(struct ir* ir);
|
static struct ir* appendir(struct ir* ir);
|
||||||
|
|
||||||
static void reset_stack(void)
|
static void reset_stack(void)
|
||||||
|
@ -37,8 +37,10 @@ static struct ir* pop(int size)
|
||||||
if (size < EM_wordsize)
|
if (size < EM_wordsize)
|
||||||
size = EM_wordsize;
|
size = EM_wordsize;
|
||||||
return
|
return
|
||||||
new_ir0(
|
appendir(
|
||||||
IR_POP, size
|
new_ir0(
|
||||||
|
IR_POP, size
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -60,13 +62,25 @@ static void print_stack(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("\t; stack:");
|
tracef('E', "E: stack:");
|
||||||
for (i=0; i<stackptr; i++)
|
for (i=0; i<stackptr; i++)
|
||||||
{
|
{
|
||||||
struct ir* ir = stack[i];
|
struct ir* ir = stack[i];
|
||||||
printf(" $%d.%d", ir->id, ir->size);
|
tracef('E', " $%d.%d", ir->id, ir->size);
|
||||||
}
|
}
|
||||||
printf(" (top)\n");
|
tracef('E', " (top)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendallirs(struct ir* ir)
|
||||||
|
{
|
||||||
|
if (CONTAINS(current_bb->allirs, ir))
|
||||||
|
fatal("ir reachable from more than one place");
|
||||||
|
|
||||||
|
APPEND(current_bb->allirs, ir);
|
||||||
|
if (ir->left && !ir->left->is_sequence)
|
||||||
|
appendallirs(ir->left);
|
||||||
|
if (ir->right && !ir->right->is_sequence)
|
||||||
|
appendallirs(ir->right);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ir* appendir(struct ir* ir)
|
static struct ir* appendir(struct ir* ir)
|
||||||
|
@ -76,8 +90,9 @@ static struct ir* appendir(struct ir* ir)
|
||||||
assert(current_bb != NULL);
|
assert(current_bb != NULL);
|
||||||
ir->is_sequence = true;
|
ir->is_sequence = true;
|
||||||
APPEND(current_bb->irs, ir);
|
APPEND(current_bb->irs, ir);
|
||||||
|
appendallirs(ir);
|
||||||
|
|
||||||
ir_print(ir);
|
ir_print('0', ir);
|
||||||
return ir;
|
return ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,16 +127,6 @@ void tb_regvar(arith offset, int size, int type, int priority)
|
||||||
/* ignored */
|
/* ignored */
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ir* address_of_local(int index)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
new_ir2(
|
|
||||||
IR_ADD, EM_pointersize,
|
|
||||||
new_regir((index < 0) ? IRR_LB : IRR_AB),
|
|
||||||
new_wordir(index)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ir* address_of_external(const char* label, arith offset)
|
static struct ir* address_of_external(const char* label, arith offset)
|
||||||
{
|
{
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
|
@ -162,7 +167,7 @@ static struct ir* tristate_compare(int size, int opcode)
|
||||||
|
|
||||||
return
|
return
|
||||||
new_ir2(
|
new_ir2(
|
||||||
opcode, size,
|
opcode, EM_wordsize,
|
||||||
left, right
|
left, right
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -173,8 +178,8 @@ static void simple_convert(int opcode)
|
||||||
struct ir* srcsize = pop(EM_wordsize);
|
struct ir* srcsize = pop(EM_wordsize);
|
||||||
struct ir* value;
|
struct ir* value;
|
||||||
|
|
||||||
assert(srcsize->opcode == IR_ICONST);
|
assert(srcsize->opcode == IR_CONST);
|
||||||
assert(destsize->opcode == IR_ICONST);
|
assert(destsize->opcode == IR_CONST);
|
||||||
|
|
||||||
value = pop(srcsize->u.ivalue);
|
value = pop(srcsize->u.ivalue);
|
||||||
push(
|
push(
|
||||||
|
@ -241,7 +246,7 @@ static void simple_branch2(int opcode, int size,
|
||||||
new_ir2(
|
new_ir2(
|
||||||
IR_CJUMP, 0,
|
IR_CJUMP, 0,
|
||||||
new_ir2(
|
new_ir2(
|
||||||
irop, size,
|
irop, size,
|
||||||
left, right
|
left, right
|
||||||
),
|
),
|
||||||
new_ir2(
|
new_ir2(
|
||||||
|
@ -336,11 +341,17 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
case op_xor: simple_alu2(opcode, value, IR_EOR); break;
|
case op_xor: simple_alu2(opcode, value, IR_EOR); break;
|
||||||
case op_com: simple_alu1(opcode, value, IR_NOT); break;
|
case op_com: simple_alu1(opcode, value, IR_NOT); break;
|
||||||
|
|
||||||
|
case op_adf: simple_alu2(opcode, value, IR_ADDF); break;
|
||||||
|
case op_sbf: simple_alu2(opcode, value, IR_SUBF); break;
|
||||||
|
case op_mlf: simple_alu2(opcode, value, IR_MULF); break;
|
||||||
|
case op_dvf: simple_alu2(opcode, value, IR_DIVF); break;
|
||||||
|
case op_ngf: simple_alu1(opcode, value, IR_NEGF); break;
|
||||||
|
|
||||||
case op_lol:
|
case op_lol:
|
||||||
push(
|
push(
|
||||||
new_ir1(
|
new_ir1(
|
||||||
IR_LOAD, EM_wordsize,
|
IR_LOAD, EM_wordsize,
|
||||||
address_of_local(value)
|
new_localir(value)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -349,7 +360,7 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
appendir(
|
appendir(
|
||||||
new_ir2(
|
new_ir2(
|
||||||
IR_STORE, EM_wordsize,
|
IR_STORE, EM_wordsize,
|
||||||
address_of_local(value),
|
new_localir(value),
|
||||||
pop(EM_wordsize)
|
pop(EM_wordsize)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -357,7 +368,7 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
|
|
||||||
case op_lal:
|
case op_lal:
|
||||||
push(
|
push(
|
||||||
address_of_local(value)
|
new_localir(value)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -476,17 +487,21 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
appendir(
|
while ((value > 0) && (stackptr > 0))
|
||||||
new_ir2(
|
{
|
||||||
IR_SETREG, EM_pointersize,
|
struct ir* ir = pop(stack[stackptr-1]->size);
|
||||||
new_regir(IRR_SP),
|
value -= ir->size;
|
||||||
new_ir2(
|
}
|
||||||
IR_ADD, EM_pointersize,
|
|
||||||
new_regir(IRR_SP),
|
if (value != 0)
|
||||||
|
{
|
||||||
|
appendir(
|
||||||
|
new_ir1(
|
||||||
|
IR_STACKADJUST, EM_pointersize,
|
||||||
new_wordir(value)
|
new_wordir(value)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
);
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -497,10 +512,10 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
if (value > 0)
|
if (value > 0)
|
||||||
{
|
{
|
||||||
struct ir* retval = pop(value);
|
struct ir* retval = pop(value);
|
||||||
|
materialise_stack();
|
||||||
appendir(
|
appendir(
|
||||||
new_ir2(
|
new_ir1(
|
||||||
IR_SETREG, value,
|
IR_SETRET, value,
|
||||||
new_regir(IRR_RR),
|
|
||||||
retval
|
retval
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -518,9 +533,8 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
{
|
{
|
||||||
push(
|
push(
|
||||||
appendir(
|
appendir(
|
||||||
new_ir1(
|
new_ir0(
|
||||||
IR_GETREG, value,
|
IR_GETRET, value
|
||||||
new_regir(IRR_RR)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -630,13 +644,7 @@ static void generate_tree(struct basicblock* bb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("; BLOCK %s\n", bb->name);
|
tracef('0', "0: block %s\n", bb->name);
|
||||||
if (bb->inblocks_count > 0)
|
|
||||||
{
|
|
||||||
printf("; Entered from:\n");
|
|
||||||
for (i=0; i<bb->inblocks_count; i++)
|
|
||||||
printf("; %s\n", bb->inblocks[i]->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
current_bb = bb;
|
current_bb = bb;
|
||||||
reset_stack();
|
reset_stack();
|
||||||
|
@ -644,30 +652,30 @@ static void generate_tree(struct basicblock* bb)
|
||||||
for (i=0; i<bb->insns_count; i++)
|
for (i=0; i<bb->insns_count; i++)
|
||||||
{
|
{
|
||||||
struct insn* insn = bb->insns[i];
|
struct insn* insn = bb->insns[i];
|
||||||
printf("\t; EM: %s ", em_mnem[insn->opcode - sp_fmnem]);
|
tracef('E', "E: read %s ", em_mnem[insn->opcode - sp_fmnem]);
|
||||||
switch (insn->paramtype)
|
switch (insn->paramtype)
|
||||||
{
|
{
|
||||||
case PARAM_NONE:
|
case PARAM_NONE:
|
||||||
printf("\n");
|
tracef('E', "\n");
|
||||||
insn_simple(insn->opcode);
|
insn_simple(insn->opcode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARAM_IVALUE:
|
case PARAM_IVALUE:
|
||||||
printf("value=%d\n", insn->u.ivalue);
|
tracef('E', "value=%d\n", insn->u.ivalue);
|
||||||
insn_ivalue(insn->opcode, insn->u.ivalue);
|
insn_ivalue(insn->opcode, insn->u.ivalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARAM_LVALUE:
|
case PARAM_LVALUE:
|
||||||
printf("label=%s offset=%d\n",
|
tracef('E', "label=%s offset=%d\n",
|
||||||
insn->u.lvalue.label, insn->u.lvalue.offset);
|
insn->u.lvalue.label, insn->u.lvalue.offset);
|
||||||
insn_lvalue(insn->opcode, insn->u.lvalue.label, insn->u.lvalue.offset);
|
insn_lvalue(insn->opcode, insn->u.lvalue.label, insn->u.lvalue.offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARAM_BVALUE:
|
case PARAM_BVALUE:
|
||||||
printf("true=%s", insn->u.bvalue.left->name);
|
tracef('E', "true=%s", insn->u.bvalue.left->name);
|
||||||
if (insn->u.bvalue.right)
|
if (insn->u.bvalue.right)
|
||||||
printf(" false=%s", insn->u.bvalue.right->name);
|
tracef('E', " false=%s", insn->u.bvalue.right->name);
|
||||||
printf("\n");
|
tracef('E', "\n");
|
||||||
insn_bvalue(insn->opcode, insn->u.bvalue.left, insn->u.bvalue.right);
|
insn_bvalue(insn->opcode, insn->u.bvalue.left, insn->u.bvalue.right);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -675,18 +683,11 @@ static void generate_tree(struct basicblock* bb)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_stack();
|
if (tracing('E'))
|
||||||
|
print_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(stackptr == 0);
|
assert(stackptr == 0);
|
||||||
|
|
||||||
if (bb->outblocks_count > 0)
|
|
||||||
{
|
|
||||||
printf("; Exiting to:\n");
|
|
||||||
for (i=0; i<bb->outblocks_count; i++)
|
|
||||||
printf("; %s\n", bb->outblocks[i]->name);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tb_procedure(struct procedure* current_proc)
|
void tb_procedure(struct procedure* current_proc)
|
||||||
|
|
Loading…
Reference in a new issue