vars = {
["+cflags"] = {
"-Werror-implicit-function-declaration",
- "-Wint-conversion"
}
}
}
#include "mcg.h"
-static char outbuf[256];
+static int hop_count = 1;
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->id = hop_count++;
hop->insn_no = insn_no;
hop->ir = ir;
return hop;
}
-static void append(const char* fmt, ...)
+static struct insel* new_insel(enum insel_type type)
{
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(outbuf + strlen(outbuf), fmt, ap);
- va_end(ap);
+ struct insel* insel = calloc(1, sizeof(*insel));
+ insel->type = type;
+ return insel;
}
-static void emit_reg(struct ir* ir)
+void hop_add_string_insel(struct hop* hop, const char* string)
{
- 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);
- }
+ struct insel* insel = new_insel(INSEL_STRING);
+ insel->u.string = string;
+ array_append(&hop->insels, insel);
}
-static void emit_string(const char* data)
+void hop_add_reg_insel(struct hop* hop, struct hop* reg)
{
- append("%s", data);
+ struct insel* insel = new_insel(INSEL_REG);
+ insel->u.reg = reg;
+ array_append(&hop->insels, insel);
}
-static void emit_value(struct ir* ir)
+void hop_add_value_insel(struct hop* hop, struct ir* ir)
{
- append("(val)");
+ struct insel* insel = new_insel(INSEL_VALUE);
+ insel->u.value = ir;
+ array_append(&hop->insels, insel);
}
-static void emit_resultreg(void)
+void hop_add_eoi_insel(struct hop* hop)
{
- append("%%%d", current_hop->resultvreg->id);
+ struct insel* insel = new_insel(INSEL_EOI);
+ array_append(&hop->insels, insel);
}
-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];
+ int i;
+ bool soi = true;
- current_hop = hop;
- outbuf[0] = 0;
- if (insndata->emitter)
+ i = 0;
+ for (i=0; i<hop->insels.count; i++)
{
- insndata->emitter(hop->ir, &emitter_data);
+ struct insel* insel = hop->insels.item[i];
- s = strtok(outbuf, "\n");
- do
+ if (soi)
{
- tracef(k, "%c: %p: %s\n", k, hop, s);
- s = strtok(NULL, "\n");
+ tracef(k, "%c: %d: ", k, hop->id);
+ soi = false;
+ }
+
+ switch (insel->type)
+ {
+ case INSEL_EOI:
+ tracef(k, "\n");
+ soi = true;
+ break;
+
+ case INSEL_REG:
+ tracef(k, "%%%d", insel->u.reg->id);
+ break;
+
+ case INSEL_STRING:
+ tracef(k, "%s", insel->u.string);
+ break;
+
+ case INSEL_VALUE:
+ {
+ struct ir* ir = insel->u.value;
+ switch (ir->opcode)
+ {
+ case IR_BLOCK:
+ tracef(k, "%s", ir->u.bvalue->name);
+ break;
+
+ case IR_LOCAL:
+ case IR_CONST:
+ tracef(k, "0x%d", ir->u.ivalue);
+ break;
+ }
+ break;
+ }
}
- while (s);
}
- else
- tracef(k, "%c: %p: (empty)\n", k, hop);
+
+ if (!soi)
+ tracef(k, "\n", k);
}
#ifndef HOP_H
#define HOP_H
+enum insel_type
+{
+ INSEL_STRING,
+ INSEL_REG,
+ INSEL_VALUE,
+ INSEL_EOI
+};
+
+struct insel
+{
+ enum insel_type type;
+ union
+ {
+ const char* string;
+ struct hop* reg;
+ struct ir* value;
+ }
+ u;
+};
+
struct hop
{
+ int id;
int insn_no;
struct ir* ir;
- struct vreg* resultvreg;
- ARRAYOF(struct vreg) invregs;
- ARRAYOF(struct vreg) outvregs;
- ARRAYOF(struct vreg) newvregs;
- ARRAYOF(struct vreg) deadvregs;
+ struct hop* result;
+ ARRAYOF(struct hop) params;
+ ARRAYOF(struct insel) insels;
};
extern struct hop* new_hop(int insn_no, struct ir* ir);
+extern void hop_add_string_insel(struct hop* hop, const char* string);
+extern void hop_add_reg_insel(struct hop* hop, struct hop* reg);
+extern void hop_add_value_insel(struct hop* hop, struct ir* ir);
+extern void hop_add_eoi_insel(struct hop* hop);
+
extern void hop_print(char k, struct hop* hop);
#endif
#include "map.h"
#include "ir.h"
#include "mcgg.h"
-#include "vreg.h"
#include "hop.h"
extern char em_pseu[][4];
#include "mcg.h"
static struct basicblock* current_bb;
+static struct hop* current_hop;
+
+static const struct burm_emitter_data emitter_data;
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 void walk_instructions(struct hop* hop, struct ir* ir, int goal)
+static void emit_reg(struct ir* ir)
+{
+ if (ir->hop)
+ hop_add_reg_insel(current_hop, ir->hop);
+ else
+ {
+ const struct burm_instruction_data* insndata = &burm_instruction_data[ir->insn_no];
+ if (insndata->emitter)
+ insndata->emitter(ir, &emitter_data);
+ }
+}
+
+static void emit_string(const char* data)
+{
+ hop_add_string_insel(current_hop, data);
+}
+
+static void emit_value(struct ir* ir)
+{
+ hop_add_value_insel(current_hop, ir);
+}
+
+static void emit_resultreg(void)
+{
+ hop_add_reg_insel(current_hop, current_hop);
+}
+
+static void emit_eoi(void)
+{
+ hop_add_eoi_insel(current_hop);
+}
+
+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)
{
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];
+ struct hop* parent_hop = NULL;
int i;
ir->insn_no = insn_no;
if (!insndata->is_fragment)
- hop = ir->hop = new_hop(insn_no, ir);;
-
- if (insndata->allocate)
{
- hop->resultvreg = new_vreg();
- array_append(&hop->newvregs, hop->resultvreg);
- array_append(&hop->outvregs, hop->resultvreg);
+ parent_hop = current_hop;
+ current_hop = ir->hop = new_hop(insn_no, ir);
}
burm_kids(ir, insn_no, children);
for (i=0; nts[i]; i++)
- walk_instructions(hop, children[i], nts[i]);
+ walk_instructions(children[i], nts[i]);
ir->is_generated = true;
if (!insndata->is_fragment)
{
- array_append(¤t_bb->hops, hop);
- hop_print('I', hop);
+ if (insndata->emitter)
+ insndata->emitter(ir, &emitter_data);
+
+ hop_print('I', current_hop);
+ array_append(¤t_bb->hops, current_hop);
+ current_hop = parent_hop;
}
}
burm_panic_cannot_match(ir);
ir_print('I', ir);
- walk_instructions(NULL, ir, 1);
+ walk_instructions(ir, 1);
}
}
aluparam fragment;
reg allocates(GPR);
tristate allocates(CC);
+ bistate allocates(CC);
PATTERNS
emit "b $false"
cost 8;
+ CJUMPEQ(value:bistate, PAIR(true:BLOCK4, false:BLOCK4))
+ emit "beq $true"
+ emit "b $false"
+ cost 8;
+
/* Comparisons */
emit "cmp %left, %right"
cost 4;
+ bistate = COMPARES4(COMPARES4(left:reg, right:aluparam), CONST4)
+ emit "cmp %left, %right"
+ cost 4;
+
reg = tristate
emit "mov %reg, #0"
emit "movlt %reg, #-1"
emit "movgt %reg, #1"
cost 12;
+ reg = bistate
+ emit "moveq %reg, #1"
+ emit "movne %reg, #0"
+ cost 8;
+
/* Conversions */
+++ /dev/null
-#include "mcg.h"
-
-static int vreg_count = 0;
-
-struct vreg* new_vreg(void)
-{
- struct vreg* vreg = calloc(1, sizeof *vreg);
- vreg->id = vreg_count++;
- return vreg;
-}
+++ /dev/null
-#ifndef VREG_H
-#define VREG_H
-
-struct vreg
-{
- int id;
-};
-
-extern struct vreg* new_vreg(void);
-
-#endif
-
-