Refactored the way hops are rendered; add support for emitting code (although
authorDavid Given <dg@cowlark.com>
Mon, 10 Oct 2016 22:12:11 +0000 (00:12 +0200)
committerDavid Given <dg@cowlark.com>
Mon, 10 Oct 2016 22:12:11 +0000 (00:12 +0200)
with no prologue or epilogue yet).

mach/proto/mcg/data.c
mach/proto/mcg/hop.c
mach/proto/mcg/hop.h
mach/proto/mcg/main.c
mach/proto/mcg/mcg.h
mach/proto/mcg/procedure.c

index acc14c0..0f79cb7 100644 (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 : */
index 68b7762..f987313 100644 (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;
+
+    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; 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 : */
index 34d5c11..7dcbfd8 100644 (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
index 235e9f3..1c0d706 100644 (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;
 }
 
index e1b8083..5678858 100644 (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;
 
index 329c384..35b986f 100644 (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)