diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c new file mode 100644 index 000000000..ccc180540 --- /dev/null +++ b/mach/proto/mcg/hop.c @@ -0,0 +1,39 @@ +#include "mcg.h" + +struct hop* new_hop(int insn_no, struct ir* ir) +{ + struct hop* hop = calloc(1, sizeof *hop); + hop->insn_no = insn_no; + hop->ir = ir; +} + +static void add_reg(struct vreg* vregs[], struct vreg* vreg) +{ + int i; + + for (i=0; iinvregs, vreg); +} + +void hop_add_out_reg(struct hop* hop, struct vreg* vreg) +{ + add_reg(hop->outvregs, vreg); +} + +void hop_emit(struct hop* hop, const struct burm_emitter_data* ed) +{ + const struct burm_instruction_data* insndata = &burm_instruction_data[hop->insn_no]; + insndata->emitter(hop->ir, ed); +} + diff --git a/mach/proto/mcg/hop.h b/mach/proto/mcg/hop.h new file mode 100644 index 000000000..d6cc6e79d --- /dev/null +++ b/mach/proto/mcg/hop.h @@ -0,0 +1,27 @@ +#ifndef HOP_H +#define HOP_H + +struct vreg +{ + int id; + int regclass; +}; + +#define HOP_INOUT_REGS 4 + +struct hop +{ + int insn_no; + struct ir* ir; + struct vreg* invregs[HOP_INOUT_REGS]; + struct vreg* outvregs[HOP_INOUT_REGS]; +}; + +extern struct hop* new_hop(int insn_no, struct ir* ir); + +extern void hop_add_in_reg(struct hop* hop, struct vreg* reg); +extern void hop_add_out_reg(struct hop* hop, struct vreg* reg); + +#endif + + diff --git a/mach/proto/mcg/ir.h b/mach/proto/mcg/ir.h index 5868551db..ac01f1633 100644 --- a/mach/proto/mcg/ir.h +++ b/mach/proto/mcg/ir.h @@ -36,6 +36,7 @@ struct ir void* state_label; /* used by the iburg instruction selector */ int insn_no; + int vreg; bool is_sequence : 1; bool is_generated : 1; diff --git a/mach/proto/mcg/mcg.h b/mach/proto/mcg/mcg.h index a5a148847..45bb691c6 100644 --- a/mach/proto/mcg/mcg.h +++ b/mach/proto/mcg/mcg.h @@ -19,6 +19,8 @@ #include "array.h" #include "map.h" #include "ir.h" +#include "mcgg.h" +#include "hop.h" extern char em_pseu[][4]; extern char em_mnem[][4]; @@ -80,6 +82,7 @@ struct basicblock const char* name; ARRAY(struct em, ems); ARRAY(struct ir, irs); + ARRAY(struct hop, hops); bool is_fake : 1; bool is_root : 1; bool is_terminated : 1; diff --git a/mach/proto/mcg/pass_instructionselection.c b/mach/proto/mcg/pass_instructionselection.c index dd386a77b..aebfd9160 100644 --- a/mach/proto/mcg/pass_instructionselection.c +++ b/mach/proto/mcg/pass_instructionselection.c @@ -1,5 +1,6 @@ #include "mcg.h" -#include "mcgg.h" + +static int vregcount; #if 0 static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) { @@ -26,8 +27,8 @@ static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) { void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) { const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno]; - tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p, - insndata->name, cost, bestcost); + //tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p, + // insndata->name, cost, bestcost); } void burm_panic_cannot_match(struct ir* ir) @@ -51,7 +52,7 @@ static void emit_reg(struct ir* ir) if (insndata->is_fragment) insndata->emitter(ir, &emitter_data); else - tracef('I', "I: emit reg $%d\n", ir->id); + tracef('I', "I: emit reg %d\n", ir->vreg); } static void emit_value(struct ir* ir) @@ -85,13 +86,26 @@ static void walk_instructions(struct ir* ir, int goal) const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no]; const short* nts = burm_nts[insn_no]; int i; + int resultreg = 0; ir->insn_no = insn_no; + if (insndata->allocate) + { + resultreg = vregcount++; + tracef('I', "I: new %s %d\n", + burm_register_class_names[insndata->allocate], resultreg); + } + burm_kids(ir, insn_no, children); for (i=0; nts[i]; i++) walk_instructions(children[i], nts[i]); + if (ir->vreg) + tracef('I', "I: use %d\n", ir->vreg); + if (resultreg) + ir->vreg = resultreg; + tracef('I', "I: $%d %s selected %s %d: %s\n", ir->id, ir->is_sequence ? "S" : " ", @@ -100,8 +114,6 @@ static void walk_instructions(struct ir* ir, int goal) insndata->name); ir->is_generated = true; - if (insndata->allocate) - tracef('I', "I: allocate reg of class %d\n", insndata->allocate); if (!insndata->is_fragment && insndata->emitter) insndata->emitter(ir, &emitter_data); } @@ -131,6 +143,8 @@ void pass_instruction_selector(struct procedure* proc) { int i; + vregcount = 1; + for (i=0; iblocks_count; i++) { struct basicblock* bb = proc->blocks[i]; diff --git a/util/mcgg/mcgg.h b/util/mcgg/mcgg.h index 9c15eea82..004146bb3 100644 --- a/util/mcgg/mcgg.h +++ b/util/mcgg/mcgg.h @@ -31,6 +31,7 @@ struct burm_emitter_data void (*emit_value)(struct ir* ir); void (*emit_resultreg)(void); void (*emit_eoi)(void); + void (*emit_usereg)(struct ir* ir); }; typedef void burm_emitter_t(struct ir* ir, const struct burm_emitter_data* data); @@ -44,6 +45,7 @@ struct burm_instruction_data }; extern const struct burm_instruction_data burm_instruction_data[]; +extern const char* burm_register_class_names[]; #endif