2016-09-25 21:29:59 +00:00
|
|
|
#include "mcg.h"
|
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
static char outbuf[256];
|
|
|
|
static struct hop* current_hop;
|
|
|
|
|
|
|
|
static const struct burm_emitter_data emitter_data;
|
|
|
|
|
2016-09-25 21:29:59 +00:00
|
|
|
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;
|
2016-09-26 22:19:45 +00:00
|
|
|
return hop;
|
2016-09-25 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
static void append(const char* fmt, ...)
|
2016-09-25 21:29:59 +00:00
|
|
|
{
|
2016-09-26 22:19:45 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vsprintf(outbuf + strlen(outbuf), fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
2016-09-25 21:29:59 +00:00
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2016-09-25 21:29:59 +00:00
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
static void emit_string(const char* data)
|
|
|
|
{
|
|
|
|
append("%s", data);
|
2016-09-25 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
static void emit_value(struct ir* ir)
|
2016-09-25 21:29:59 +00:00
|
|
|
{
|
2016-09-26 22:19:45 +00:00
|
|
|
append("(val)");
|
2016-09-25 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
static void emit_resultreg(void)
|
2016-09-25 21:29:59 +00:00
|
|
|
{
|
2016-09-26 22:19:45 +00:00
|
|
|
append("%%%d", current_hop->resultvreg->id);
|
2016-09-25 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 22:19:45 +00:00
|
|
|
static void emit_eoi(void)
|
2016-09-25 21:29:59 +00:00
|
|
|
{
|
2016-09-26 22:19:45 +00:00
|
|
|
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;
|
2016-09-25 21:29:59 +00:00
|
|
|
const struct burm_instruction_data* insndata = &burm_instruction_data[hop->insn_no];
|
2016-09-26 22:19:45 +00:00
|
|
|
|
|
|
|
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);
|
2016-09-25 21:29:59 +00:00
|
|
|
}
|
|
|
|
|