Refactored the way hops are rendered; add support for emitting code (although
with no prologue or epilogue yet).
This commit is contained in:
parent
92bd1ac5f4
commit
e93c58dc8d
|
@ -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 : */
|
||||
|
|
|
@ -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 n;
|
||||
char* p;
|
||||
va_list ap;
|
||||
|
||||
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;
|
||||
bool soi = false;
|
||||
|
||||
print_header(k, hop);
|
||||
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 : */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,18 +72,34 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue