[Liboil-commit] 2 commits - orc/orcprogram-x86.c orc/orcprogram.c orc/orcprogram.h

David Schleef ds at kemper.freedesktop.org
Sat May 17 10:20:11 PDT 2008


 orc/orcprogram-x86.c |   37 +++++++++++++++++++++++++----------
 orc/orcprogram.c     |   53 ++++++++++++++++++++++++++++++++++++++++++++++-----
 orc/orcprogram.h     |    6 +++++
 3 files changed, 81 insertions(+), 15 deletions(-)

New commits:
commit db3dd6f982e20135e4702e2fcb47ad9face8ced4
Author: David Schleef <ds at ginger.bigkitten.com>
Date:   Sat May 17 10:08:45 2008 -0700

    [orc] implement register chaining

diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
index 16f1579..b32bd2c 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -136,7 +136,7 @@ x86_do_fixups (OrcProgram *program)
   }
 }
 
-static OrcRuleList *orc_x86_list;
+OrcRuleList *orc_x86_list;
 
 void
 orc_x86_init (void)
@@ -176,12 +176,17 @@ orc_program_compile_x86 (OrcProgram *program)
     insn = program->insns + j;
     opcode = insn->opcode;
 
-    printf("# %d: %s\n", j, insn->opcode->name);
+    printf("# %d: %s", j, insn->opcode->name);
 
     /* set up args */
     for(k=0;k<opcode->n_src + opcode->n_dest;k++){
       args[k] = program->vars + insn->args[k];
+      printf(" %d", args[k]->alloc);
+      if (args[k]->is_chained) {
+        printf(" (chained)");
+      }
     }
+    printf("\n");
 
     for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
       switch (args[k]->vartype) {
@@ -205,9 +210,9 @@ orc_program_compile_x86 (OrcProgram *program)
       }
     }
 
-    rule = orc_rule_list_get (orc_x86_list, opcode);
+    rule = insn->rule;
     if (rule) {
-      if (!(rule->flags & ORC_RULE_3REG) && insn->args[0] != insn->args[1]) {
+      if (!(rule->flags & ORC_RULE_3REG) && args[0]->alloc != args[1]->alloc) {
         x86_emit_mov_reg_reg (program, 2, args[1]->alloc, args[0]->alloc);
       }
       rule->emit (program, rule->emit_user, insn);
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index a0244bc..f93a1b9 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -121,6 +121,17 @@ orc_program_append (OrcProgram *program, const char *name, int arg0,
   program->n_insns++;
 }
 
+void
+orc_program_assign_rules (OrcProgram *program)
+{
+  int i;
+
+  for(i=0;i<program->n_insns;i++) {
+    program->insns[i].rule = orc_rule_list_get (orc_x86_list,
+        program->insns[i].opcode);
+  }
+}
+
 
 void
 orc_program_rewrite_vars (OrcProgram *program)
@@ -134,6 +145,8 @@ orc_program_rewrite_vars (OrcProgram *program)
   int actual_var;
   int alloc[8] = { 0, 1, 0, 0, 1, 1, 0, 0 };
 
+  orc_program_assign_rules (program);
+
   for(j=0;j<program->n_insns;j++){
     insn = program->insns + j;
     opcode = insn->opcode;
@@ -201,10 +214,39 @@ orc_program_rewrite_vars (OrcProgram *program)
   }
 
   for(j=0;j<program->n_insns;j++){
+#if 1
+    /* must be true to chain src1 to dest:
+     *  - rule must handle it
+     *  - src1 must be last_use
+     */
+    if (1 || program->insns[j].rule->flags & ORC_RULE_REG_REG) {
+      int src1 = program->insns[j].args[1];
+      int dest = program->insns[j].args[0];
+      if (program->vars[src1].last_use == j) {
+        if (program->vars[src1].first_use == j) {
+          for(k=0;k<8;k++){
+            if (alloc[k] == 0) {
+              program->vars[src1].alloc = k + ORC_GP_REG_BASE;
+              alloc[k] = 1;
+              program->used_regs[k] = 1;
+              break;
+            }
+          }
+          if (k==8) {
+            g_print("register overflow\n");
+          }
+        }
+        alloc[program->vars[src1].alloc - ORC_GP_REG_BASE]++;
+        program->vars[dest].alloc = program->vars[src1].alloc;
+      }
+    }
+#endif
+
     for(i=0;i<program->n_vars;i++){
       if (program->vars[i].first_use == j) {
+        if (program->vars[i].alloc) continue;
         for(k=0;k<8;k++){
-          if (!alloc[k]) {
+          if (alloc[k] == 0) {
             program->vars[i].alloc = k + ORC_GP_REG_BASE;
             alloc[k] = 1;
             program->used_regs[k] = 1;
@@ -218,18 +260,18 @@ orc_program_rewrite_vars (OrcProgram *program)
     }
     for(i=0;i<program->n_vars;i++){
       if (program->vars[i].last_use == j) {
-        alloc[program->vars[i].alloc - ORC_GP_REG_BASE] = 0;
+        alloc[program->vars[i].alloc - ORC_GP_REG_BASE]--;
       }
     }
   }
 
-#if 0
+#if 1
   for(i=0;i<program->n_vars;i++){
-    g_print("%2d: %2d %2d %s\n",
+    g_print("# %2d: %2d %2d %d\n",
         i,
         program->vars[i].first_use,
         program->vars[i].last_use,
-        x86_get_regname(program->vars[i].alloc));
+        program->vars[i].alloc);
   }
 #endif
 
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 42eb1a4..bc7b3f3 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -44,6 +44,7 @@ struct _OrcVariable {
   int replacement;
 
   int alloc;
+  int is_chained;
 
   int16_t s16;
 };
@@ -104,6 +105,7 @@ struct _OrcProgram {
   int error;
 
   int used_regs[8];
+  int alloc_regs[8];
 };
 
 struct _OrcExecutor {
@@ -186,6 +188,8 @@ OrcRule * orc_rule_list_get (OrcRuleList *rule_list, OrcOpcode *opcode);
 void orc_program_x86_register_rules (OrcRuleList *rule_list);
 void orc_program_allocate_codemem (OrcProgram *program);
 void orc_program_dump_code (OrcProgram *program);
+ 
+extern OrcRuleList *orc_x86_list;
 
 #endif
 
commit abcbb3b826a3f00d1d87fb63500ad6204f8692a7
Author: David Schleef <ds at ginger.bigkitten.com>
Date:   Fri May 16 21:10:21 2008 -0700

    [orc] keep track of registers that are used, in order to save/restore
    only those registers

diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
index 64b2381..16f1579 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -95,17 +95,29 @@ x86_emit_prologue (OrcProgram *program)
   g_print("test:\n");
   x86_emit_push (program, 4, X86_EBP);
   x86_emit_mov_memoffset_reg (program, 4, 8, X86_ESP, X86_EBP);
-  x86_emit_push (program, 4, X86_EDI);
-  x86_emit_push (program, 4, X86_ESI);
-  x86_emit_push (program, 4, X86_EBX);
+  if (program->used_regs[x86_get_regnum(X86_EDI)]) {
+    x86_emit_push (program, 4, X86_EDI);
+  }
+  if (program->used_regs[x86_get_regnum(X86_ESI)]) {
+    x86_emit_push (program, 4, X86_ESI);
+  }
+  if (program->used_regs[x86_get_regnum(X86_EBX)]) {
+    x86_emit_push (program, 4, X86_EBX);
+  }
 }
 
 void
 x86_emit_epilogue (OrcProgram *program)
 {
-  x86_emit_pop (program, 4, X86_EBX);
-  x86_emit_pop (program, 4, X86_ESI);
-  x86_emit_pop (program, 4, X86_EDI);
+  if (program->used_regs[x86_get_regnum(X86_EBX)]) {
+    x86_emit_pop (program, 4, X86_EBX);
+  }
+  if (program->used_regs[x86_get_regnum(X86_ESI)]) {
+    x86_emit_pop (program, 4, X86_ESI);
+  }
+  if (program->used_regs[x86_get_regnum(X86_EDI)]) {
+    x86_emit_pop (program, 4, X86_EDI);
+  }
   x86_emit_pop (program, 4, X86_EBP);
   x86_emit_ret (program);
 }
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index 591902d..a0244bc 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -207,6 +207,7 @@ orc_program_rewrite_vars (OrcProgram *program)
           if (!alloc[k]) {
             program->vars[i].alloc = k + ORC_GP_REG_BASE;
             alloc[k] = 1;
+            program->used_regs[k] = 1;
             break;
           }
         }
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 2ef5671..42eb1a4 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -102,6 +102,8 @@ struct _OrcProgram {
   unsigned char *labels[100];
 
   int error;
+
+  int used_regs[8];
 };
 
 struct _OrcExecutor {


More information about the Liboil-commit mailing list