Start factoring out the hardware op code.
authorDavid Given <dg@cowlark.com>
Sun, 25 Sep 2016 21:29:59 +0000 (23:29 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 25 Sep 2016 21:29:59 +0000 (23:29 +0200)
mach/proto/mcg/hop.c [new file with mode: 0644]
mach/proto/mcg/hop.h [new file with mode: 0644]
mach/proto/mcg/ir.h
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_instructionselection.c
util/mcgg/mcgg.h

diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c
new file mode 100644 (file)
index 0000000..ccc1805
--- /dev/null
@@ -0,0 +1,39 @@
+#include "mcg.h"
+
+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;
+}
+
+static void add_reg(struct vreg* vregs[], struct vreg* vreg)
+{
+       int i;
+
+       for (i=0; i<HOP_INOUT_REGS; i++)
+               if (!vregs[i])
+               {
+                       vregs[i] = vreg;
+                       return;
+               }
+
+       fatal("too many input registers for instruction");
+}
+
+void hop_add_in_reg(struct hop* hop, struct vreg* vreg)
+{
+       add_reg(hop->invregs, vreg);
+}
+
+void hop_add_out_reg(struct hop* hop, struct vreg* vreg)
+{
+       add_reg(hop->outvregs, vreg);
+}
+
+void hop_emit(struct hop* hop, const struct burm_emitter_data* ed)
+{
+    const struct burm_instruction_data* insndata = &burm_instruction_data[hop->insn_no];
+       insndata->emitter(hop->ir, ed);
+}
+
diff --git a/mach/proto/mcg/hop.h b/mach/proto/mcg/hop.h
new file mode 100644 (file)
index 0000000..d6cc6e7
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef HOP_H
+#define HOP_H
+
+struct vreg
+{
+       int id;
+       int regclass;
+};
+
+#define HOP_INOUT_REGS 4
+
+struct hop
+{
+       int insn_no;
+       struct ir* ir;
+       struct vreg* invregs[HOP_INOUT_REGS];
+       struct vreg* outvregs[HOP_INOUT_REGS];
+};
+
+extern struct hop* new_hop(int insn_no, struct ir* ir);
+
+extern void hop_add_in_reg(struct hop* hop, struct vreg* reg);
+extern void hop_add_out_reg(struct hop* hop, struct vreg* reg);
+
+#endif
+
+
index 5868551..ac01f16 100644 (file)
@@ -36,6 +36,7 @@ struct ir
 
        void* state_label; /* used by the iburg instruction selector */
        int insn_no;
+       int vreg;
 
        bool is_sequence : 1;
        bool is_generated : 1;
index a5a1488..45bb691 100644 (file)
@@ -19,6 +19,8 @@
 #include "array.h"
 #include "map.h"
 #include "ir.h"
+#include "mcgg.h"
+#include "hop.h"
 
 extern char em_pseu[][4];
 extern char em_mnem[][4];
@@ -80,6 +82,7 @@ struct basicblock
     const char* name;
     ARRAY(struct em, ems);
     ARRAY(struct ir, irs);
+    ARRAY(struct hop, hops);
     bool is_fake : 1;
     bool is_root : 1;
     bool is_terminated : 1;
index dd386a7..aebfd91 100644 (file)
@@ -1,5 +1,6 @@
 #include "mcg.h"
-#include "mcgg.h"
+
+static int vregcount;
 
 #if 0
 static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
@@ -26,8 +27,8 @@ static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
 
 void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
     const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
-       tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
-               insndata->name, cost, bestcost);
+       //tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
+       //      insndata->name, cost, bestcost);
 }
 
 void burm_panic_cannot_match(struct ir* ir)
@@ -51,7 +52,7 @@ static void emit_reg(struct ir* ir)
     if (insndata->is_fragment)
         insndata->emitter(ir, &emitter_data);
     else
-        tracef('I', "I: emit reg $%d\n", ir->id);
+        tracef('I', "I: emit reg %d\n", ir->vreg);
 }
 
 static void emit_value(struct ir* ir)
@@ -85,13 +86,26 @@ static void walk_instructions(struct ir* ir, int goal)
     const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
     const short* nts = burm_nts[insn_no];
     int i;
+    int resultreg = 0;
 
     ir->insn_no = insn_no;
 
+    if (insndata->allocate)
+    {
+        resultreg = vregcount++;
+        tracef('I', "I: new %s %d\n",
+            burm_register_class_names[insndata->allocate], resultreg);
+    }
+
     burm_kids(ir, insn_no, children);
     for (i=0; nts[i]; i++)
         walk_instructions(children[i], nts[i]);
 
+    if (ir->vreg)
+        tracef('I', "I: use %d\n", ir->vreg);
+    if (resultreg)
+        ir->vreg = resultreg;
+
     tracef('I', "I: $%d %s selected %s %d: %s\n",
         ir->id,
         ir->is_sequence ? "S" : " ",
@@ -100,8 +114,6 @@ static void walk_instructions(struct ir* ir, int goal)
         insndata->name);
     ir->is_generated = true;
 
-    if (insndata->allocate)
-        tracef('I', "I: allocate reg of class %d\n", insndata->allocate);
     if (!insndata->is_fragment && insndata->emitter)
         insndata->emitter(ir, &emitter_data);
 }
@@ -131,6 +143,8 @@ void pass_instruction_selector(struct procedure* proc)
 {
     int i;
 
+    vregcount = 1;
+
     for (i=0; i<proc->blocks_count; i++)
     {
         struct basicblock* bb = proc->blocks[i];
index 9c15eea..004146b 100644 (file)
@@ -31,6 +31,7 @@ struct burm_emitter_data
     void (*emit_value)(struct ir* ir);
     void (*emit_resultreg)(void);
     void (*emit_eoi)(void);
+    void (*emit_usereg)(struct ir* ir);
 };
 
 typedef void burm_emitter_t(struct ir* ir, const struct burm_emitter_data* data);
@@ -44,6 +45,7 @@ struct burm_instruction_data
 };
 
 extern const struct burm_instruction_data burm_instruction_data[];
+extern const char* burm_register_class_names[];
 
 #endif