From e93c58dc8dbca6cf45026f4fcba11aefea624270 Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 11 Oct 2016 00:12:11 +0200 Subject: [PATCH] Refactored the way hops are rendered; add support for emitting code (although with no prologue or epilogue yet). --- mach/proto/mcg/data.c | 24 +++++------ mach/proto/mcg/hop.c | 82 ++++++++++++++++++++++++++++---------- mach/proto/mcg/hop.h | 1 + mach/proto/mcg/main.c | 35 +++++++++++++--- mach/proto/mcg/mcg.h | 1 + mach/proto/mcg/procedure.c | 19 +++++++++ 6 files changed, 122 insertions(+), 40 deletions(-) diff --git a/mach/proto/mcg/data.c b/mach/proto/mcg/data.c index acc14c0fd..0f79cb767 100644 --- a/mach/proto/mcg/data.c +++ b/mach/proto/mcg/data.c @@ -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 : */ diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c index 68b776280..f9873136b 100644 --- a/mach/proto/mcg/hop.c +++ b/mach/proto/mcg/hop.c @@ -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; + + 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; +} - print_header(k, hop); +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; iinsels.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 : */ diff --git a/mach/proto/mcg/hop.h b/mach/proto/mcg/hop.h index 34d5c116f..7dcbfd87a 100644 --- a/mach/proto/mcg/hop.h +++ b/mach/proto/mcg/hop.h @@ -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 diff --git a/mach/proto/mcg/main.c b/mach/proto/mcg/main.c index 235e9f357..1c0d7065c 100644 --- a/mach/proto/mcg/main.c +++ b/mach/proto/mcg/main.c @@ -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 : "", EM_error); + if (!EM_open((char*) inputfilename)) + fatal("couldn't open input '%s': %s", + inputfilename ? inputfilename : "", 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; } diff --git a/mach/proto/mcg/mcg.h b/mach/proto/mcg/mcg.h index e1b8083e1..567885886 100644 --- a/mach/proto/mcg/mcg.h +++ b/mach/proto/mcg/mcg.h @@ -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; diff --git a/mach/proto/mcg/procedure.c b/mach/proto/mcg/procedure.c index 329c384d3..35b986f55 100644 --- a/mach/proto/mcg/procedure.c +++ b/mach/proto/mcg/procedure.c @@ -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; iname); + for (j=0; jhops.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) -- 2.34.1