Refactored the way hops are rendered; add support for emitting code (although

with no prologue or epilogue yet).
This commit is contained in:
David Given 2016-10-11 00:12:11 +02:00
parent 92bd1ac5f4
commit e93c58dc8d
6 changed files with 122 additions and 40 deletions

View file

@ -36,8 +36,8 @@ static void emit_header(int desired_section)
else if (pending->section != desired_section)
fatal("label '%s' can't change sections", pending->name);
printf("\n.sect %s\n", section_to_str(pending->section));
printf("%s:\n", pending->name);
fprintf(outputfile, "\n.sect %s\n", section_to_str(pending->section));
fprintf(outputfile, "%s:\n", pending->name);
pending = NULL;
}
}
@ -46,7 +46,7 @@ void data_int(arith data, size_t size, bool is_ro)
{
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
assert((size == 1) || (size == 2) || (size == 4) || (size == 8));
printf("\t.data%d 0x%0*lld\n", size, size*2, data);
fprintf(outputfile, "\t.data%d 0x%0*lld\n", size, size*2, data);
}
void data_block(const uint8_t* data, size_t size, bool is_ro)
@ -65,13 +65,13 @@ void data_block(const uint8_t* data, size_t size, bool is_ro)
if (start < p)
{
printf("\t.ascii \"");
fprintf(outputfile, "\t.ascii \"");
while (start < p)
{
printf("%c", *start);
fprintf(outputfile, "%c", *start);
start++;
}
printf("\"\n");
fprintf(outputfile, "\"\n");
}
while ((p < end) && !isprint(*p))
@ -81,16 +81,16 @@ void data_block(const uint8_t* data, size_t size, bool is_ro)
{
bool first = true;
printf("\t.data1 ");
fprintf(outputfile, "\t.data1 ");
while (start < p)
{
if (!first)
printf(", ");
printf("0x%02x", *start);
fprintf(outputfile, ", ");
fprintf(outputfile, "0x%02x", *start);
start++;
first = false;
}
printf("\n");
fprintf(outputfile, "\n");
}
}
}
@ -98,7 +98,7 @@ void data_block(const uint8_t* data, size_t size, bool is_ro)
void data_offset(const char* label, arith offset, bool is_ro)
{
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
printf("\t.data%d %s+%lld\n", EM_pointersize, label, offset);
fprintf(outputfile, "\t.data%d %s+%lld\n", EM_pointersize, label, offset);
}
void data_bss(arith size, int init)
@ -107,7 +107,7 @@ void data_bss(arith size, int init)
fatal("non-zero-initialised bss not supported");
emit_header(SECTION_BSS);
printf("\t.space %lld\n", size);
fprintf(outputfile, "\t.space %lld\n", size);
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -2,6 +2,9 @@
static int hop_count = 1;
static struct hop* current_hop;
static char* buffer = NULL;
static int bufferlen = 0;
static int buffersize = 0;
static const struct burm_emitter_data emitter_data;
@ -73,35 +76,54 @@ static void print_header(char k, struct hop* hop)
tracef(k, " ");
}
void hop_print(char k, struct hop* hop)
static char* appendf(const char* fmt, ...)
{
int i;
bool soi = false;
int n;
char* p;
va_list ap;
print_header(k, hop);
va_start(ap, fmt);
n = bufferlen + vsnprintf(NULL, 0, fmt, ap) + 1;
va_end(ap);
if (n > buffersize)
{
buffersize *= 2;
if (buffersize < n)
buffersize = n*2;
buffer = realloc(buffer, buffersize);
}
va_start(ap, fmt);
vsprintf(buffer+bufferlen, fmt, ap);
va_end(ap);
bufferlen = n - 1; /* remember the \0 at the end */
return p;
}
char* hop_render(struct hop* hop)
{
int i;
appendf(""); /* ensure the buffer has been allocated */
bufferlen = 0;
buffer[0] = '\0';
i = 0;
for (i=0; i<hop->insels.count; i++)
{
struct insel* insel = hop->insels.item[i];
if (soi)
{
print_header(k, hop);
soi = false;
}
switch (insel->type)
{
case INSEL_EOI:
tracef(k, "\n");
soi = true;
appendf("\n");
break;
case INSEL_HREG:
{
struct hreg* hreg = insel->u.hreg;
tracef(k, "%s", hreg->name);
appendf("%s", hreg->name);
break;
}
@ -112,14 +134,14 @@ void hop_print(char k, struct hop* hop)
if (!hreg)
hreg = pmap_findright(&hop->regsout, vreg);
if (hreg)
tracef(k, "%s", hreg->name);
appendf("%s", hreg->name);
else
tracef(k, "%%%d", vreg->id);
appendf("%%%d", vreg->id);
break;
}
case INSEL_STRING:
tracef(k, "%s", insel->u.string);
appendf("%s", insel->u.string);
break;
case INSEL_VALUE:
@ -128,16 +150,16 @@ void hop_print(char k, struct hop* hop)
switch (ir->opcode)
{
case IR_BLOCK:
tracef(k, "%s", ir->u.bvalue->name);
appendf("%s", ir->u.bvalue->name);
break;
case IR_LABEL:
tracef(k, "%s", ir->u.lvalue);
appendf("%s", ir->u.lvalue);
break;
case IR_LOCAL:
case IR_CONST:
tracef(k, "%d", ir->u.ivalue);
appendf("%d", ir->u.ivalue);
break;
}
break;
@ -145,8 +167,24 @@ void hop_print(char k, struct hop* hop)
}
}
if (!soi)
tracef(k, "\n", k);
return buffer;
}
void hop_print(char k, struct hop* hop)
{
int i;
bool soi = false;
char* p;
hop_render(hop);
p = strtok(buffer, "\n");
while (p)
{
print_header(k, hop);
tracef(k, "%s\n", p);
p = strtok(NULL, "\n");
}
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -53,6 +53,7 @@ extern void hop_add_vreg_insel(struct hop* hop, struct vreg* vreg);
extern void hop_add_value_insel(struct hop* hop, struct ir* ir);
extern void hop_add_eoi_insel(struct hop* hop);
extern char* hop_render(struct hop* hop);
extern void hop_print(char k, struct hop* hop);
#endif

View file

@ -4,6 +4,7 @@
static const char* tracechars = NULL;
FILE* outputfile = NULL;
FILE* dominance_dot_file = NULL;
FILE* cfg_dot_file = NULL;
@ -36,7 +37,9 @@ static bool find_procedures_cb(struct symbol* symbol, void* user)
int main(int argc, char* const argv[])
{
const char* inputfile = NULL;
const char* inputfilename = NULL;
const char* outputfilename = NULL;
FILE* output;
program_name = argv[0];
@ -69,19 +72,35 @@ int main(int argc, char* const argv[])
tracechars = optarg;
break;
case 'o':
if (outputfilename)
fatal("already specified an output file");
outputfilename = optarg;
break;
case 1:
if (inputfile)
if (inputfilename)
fatal("unexpected argument '%s'", optarg);
inputfile = optarg;
inputfilename = optarg;
}
}
symbol_init();
if (!EM_open((char*) inputfile))
fatal("couldn't open '%s': %s",
inputfile ? inputfile : "<stdin>", EM_error);
if (!EM_open((char*) inputfilename))
fatal("couldn't open input '%s': %s",
inputfilename ? inputfilename : "<stdin>", EM_error);
if (outputfilename)
{
outputfile = fopen(outputfilename, "w");
if (!outputfile)
fatal("couldn't open output '%s': %s",
outputfilename, strerror(errno));
}
else
outputfile = stdout;
/* Reads in the EM, outputs the data sections, parses any code and
* generates IR trees. */
@ -93,7 +112,10 @@ int main(int argc, char* const argv[])
symbol_walk(find_procedures_cb, NULL);
if (outputfilename)
fclose(outputfile);
EM_close();
if (cfg_dot_file)
{
fprintf(cfg_dot_file, "}\n");
@ -104,6 +126,7 @@ int main(int argc, char* const argv[])
fprintf(dominance_dot_file, "}\n");
fclose(dominance_dot_file);
}
return 0;
}

View file

@ -114,6 +114,7 @@ extern void pass_register_allocator(void);
extern void pass_remove_dead_blocks(struct procedure* proc);
extern void pass_split_critical_edges(struct procedure* proc);
extern FILE* outputfile;
extern FILE* dominance_dot_file;
extern FILE* cfg_dot_file;

View file

@ -104,6 +104,23 @@ static void print_hops(char k, struct procedure* proc)
}
}
static void emit_procedure(struct procedure* proc)
{
int i, j;
for (i=0; i<dominance.preorder.count; i++)
{
struct basicblock* bb = dominance.preorder.item[i];
fprintf(outputfile, "%s:\n", bb->name);
for (j=0; j<bb->hops.count; j++)
{
struct hop* hop = bb->hops.item[j];
fprintf(outputfile, "%s", hop_render(hop));
}
}
}
static void write_cfg_graph(const char* name)
{
int i;
@ -174,6 +191,8 @@ void procedure_compile(struct procedure* proc)
pass_register_allocator();
print_hops('9', proc);
emit_procedure(proc);
if (cfg_dot_file)
write_cfg_graph(proc->name);
if (dominance_dot_file)