#include "mcg.h"
+static char outbuf[256];
+static struct hop* current_hop;
+
+static const struct burm_emitter_data emitter_data;
+
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;
+ return hop;
}
-static void add_reg(struct vreg* vregs[], struct vreg* vreg)
+static void append(const char* fmt, ...)
{
- int i;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(outbuf + strlen(outbuf), fmt, ap);
+ va_end(ap);
+}
- for (i=0; i<HOP_INOUT_REGS; i++)
- if (!vregs[i])
- {
- vregs[i] = vreg;
- return;
- }
+static void emit_reg(struct ir* ir)
+{
+ struct hop* hop = ir->hop;
+ if (hop)
+ {
+ /* Reference to another hop must be its result register. */
+ append("%%%d", hop->resultvreg->id);
+ }
+ else
+ {
+ /* ...if there is no hop, it's a fragment. */
+ const struct burm_instruction_data* insndata = &burm_instruction_data[ir->insn_no];
+ insndata->emitter(ir, &emitter_data);
+ }
+}
- fatal("too many input registers for instruction");
+static void emit_string(const char* data)
+{
+ append("%s", data);
}
-void hop_add_in_reg(struct hop* hop, struct vreg* vreg)
+static void emit_value(struct ir* ir)
{
- add_reg(hop->invregs, vreg);
+ append("(val)");
}
-void hop_add_out_reg(struct hop* hop, struct vreg* vreg)
+static void emit_resultreg(void)
{
- add_reg(hop->outvregs, vreg);
+ append("%%%d", current_hop->resultvreg->id);
}
-void hop_emit(struct hop* hop, const struct burm_emitter_data* ed)
+static void emit_eoi(void)
{
+ append("\n");
+}
+
+static const struct burm_emitter_data emitter_data =
+{
+ &emit_string,
+ &emit_reg,
+ &emit_value,
+ &emit_resultreg,
+ &emit_eoi
+};
+
+void hop_print(char k, struct hop* hop)
+{
+ char* s;
const struct burm_instruction_data* insndata = &burm_instruction_data[hop->insn_no];
- insndata->emitter(hop->ir, ed);
+
+ current_hop = hop;
+ outbuf[0] = 0;
+ if (insndata->emitter)
+ {
+ insndata->emitter(hop->ir, &emitter_data);
+
+ s = strtok(outbuf, "\n");
+ do
+ {
+ tracef(k, "%c: %p: %s\n", k, hop, s);
+ s = strtok(NULL, "\n");
+ }
+ while (s);
+ }
+ else
+ tracef(k, "%c: %p: (empty)\n", k, hop);
}
#include "mcg.h"
-static int vregcount;
-
-#if 0
-static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
-#ifdef TRACE
- int eruleno = burm_rule(STATE_LABEL(p), goalnt);
- const short *nts = burm_nts[eruleno];
- NODEPTR_TYPE kids[10];
- int i;
-
- for (i = 0; i < indent; i++)
- fprintf(stderr, " ");
- fprintf(stderr, "%s\n", burm_string[eruleno]);
- burm_kids(p, eruleno, kids);
- for (i = 0; nts[i]; i++)
- {
- if (kids[i])
- dumpCover(kids[i], nts[i], indent + 1);
- else
- fprintf(stderr, "failed!\n");
- }
-#endif
-}
-#endif
+static struct basicblock* current_bb;
void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
exit(1);
}
-static const struct burm_emitter_data emitter_data;
-
-static void emit_string(const char* data)
-{
- tracef('I', "I: emit: %s\n", data);
-}
-
-static void emit_reg(struct ir* ir)
-{
- const struct burm_instruction_data* insndata = &burm_instruction_data[ir->insn_no];
- if (insndata->is_fragment)
- insndata->emitter(ir, &emitter_data);
- else
- tracef('I', "I: emit reg %d\n", ir->vreg);
-}
-
-static void emit_value(struct ir* ir)
-{
- tracef('I', "I: emit value\n");
-}
-
-static void emit_resultreg(void)
-{
- tracef('I', "I: emit resultreg\n");
-}
-
-static void emit_eoi(void)
-{
- tracef('I', "I: emit eoi\n");
-}
-
-static const struct burm_emitter_data emitter_data =
-{
- &emit_string,
- &emit_reg,
- &emit_value,
- &emit_resultreg,
- &emit_eoi
-};
-
-static void walk_instructions(struct ir* ir, int goal)
+static void walk_instructions(struct hop* hop, struct ir* ir, int goal)
{
struct ir* children[10];
int insn_no = burm_rule(ir->state_label, 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->is_fragment)
+ hop = ir->hop = new_hop(insn_no, ir);;
if (insndata->allocate)
{
- resultreg = vregcount++;
- tracef('I', "I: new %s %d\n",
- burm_register_class_names[insndata->allocate], resultreg);
+ hop->resultvreg = new_vreg();
+ array_append(&hop->newvregs, hop->resultvreg);
+ array_append(&hop->outvregs, hop->resultvreg);
}
burm_kids(ir, insn_no, children);
for (i=0; nts[i]; i++)
- walk_instructions(children[i], nts[i]);
+ walk_instructions(hop, children[i], nts[i]);
- if (ir->vreg)
- tracef('I', "I: use %d\n", ir->vreg);
- if (resultreg)
- ir->vreg = resultreg;
+ ir->is_generated = true;
tracef('I', "I: $%d %s selected %s %d: %s\n",
ir->id,
insndata->is_fragment ? "fragment" : "instruction",
insn_no,
insndata->name);
- ir->is_generated = true;
- if (!insndata->is_fragment && insndata->emitter)
- insndata->emitter(ir, &emitter_data);
+ if (!insndata->is_fragment)
+ {
+ array_append(¤t_bb->hops, hop);
+ hop_print('I', hop);
+ }
}
-static void select_instructions(struct basicblock* bb)
+static void select_instructions(void)
{
int i;
- tracef('I', "I: BLOCK: %s\n", bb->name);
+ tracef('I', "I: BLOCK: %s\n", current_bb->name);
- for (i=0; i<bb->irs.count; i++)
+ for (i=0; i<current_bb->irs.count; i++)
{
int insnno;
- struct ir* ir = bb->irs.item[i];
+ struct ir* ir = current_bb->irs.item[i];
burm_label(ir);
insnno = burm_rule(ir->state_label, 1);
if (!insnno)
burm_panic_cannot_match(ir);
- walk_instructions(ir, 1);
+ ir_print('I', ir);
+ walk_instructions(NULL, ir, 1);
}
}
{
int i;
- vregcount = 1;
-
for (i=0; i<proc->blocks.count; i++)
{
- struct basicblock* bb = proc->blocks.item[i];
- select_instructions(bb);
+ current_bb = proc->blocks.item[i];
+ select_instructions();
}
}