[Liboil-commit] examples/jit

David Schleef ds at kemper.freedesktop.org
Wed May 14 10:14:38 PDT 2008


 examples/jit/Makefile.am     |    5 
 examples/jit/jit.c           |   49 +++++-
 examples/jit/ojopcodes.c     |   20 +-
 examples/jit/ojprogram-x86.c |  334 +++++++++++++++++++++++++++++++++++++++++++
 examples/jit/ojprogram.c     |  161 +++++++++++++++++++-
 examples/jit/ojprogram.h     |  128 +++++++++++-----
 6 files changed, 629 insertions(+), 68 deletions(-)

New commits:
commit cde19e3ea598fc816ca88700d356b0f940e0eb1f
Author: David Schleef <ds at ginger.bigkitten.com>
Date:   Wed May 14 10:14:27 2008 -0700

    more jit hacking

diff --git a/examples/jit/Makefile.am b/examples/jit/Makefile.am
index 0a844a8..8c62260 100644
--- a/examples/jit/Makefile.am
+++ b/examples/jit/Makefile.am
@@ -6,6 +6,9 @@ noinst_PROGRAMS = jit
 AM_LDFLAGS = $(LIBOIL_LIBS) $(GLIB_LIBS)
 AM_CFLAGS = $(LIBOIL_CFLAGS) $(GLIB_CFLAGS)
 
-jit_SOURCES = jit.c ojprogram.c ojprogram-x86.c ojprogram.h \
+jit_SOURCES = jit.c \
+	ojprogram.c \
+	ojprogram-x86.c \
+	ojprogram.h \
 	ojopcodes.c
 
diff --git a/examples/jit/jit.c b/examples/jit/jit.c
index 7ccb751..c8aa5da 100644
--- a/examples/jit/jit.c
+++ b/examples/jit/jit.c
@@ -8,21 +8,58 @@
 
 #include "ojprogram.h"
 
+#define N 10
+
+int16_t src1[N];
+int16_t src2[N];
+int16_t dest[N];
+
 int
 main (int argc, char *argv[])
 {
   OJProgram *p;
-  int s1, s2, d1;
+  OJExecutor *ex;
+  int s1, s2, d1, offset, shift;
+  int t1;
+  int i;
+
+  oj_opcode_init ();
 
   p = oj_program_new ();
 
-  d1 = oj_program_add_destination (p, "s16");
-  s1 = oj_program_add_source (p, "s16");
-  s2 = oj_program_add_source (p, "s16");
+  d1 = oj_program_add_destination (p, "s16", "d1");
+  s1 = oj_program_add_source (p, "s16", "s1");
+  s2 = oj_program_add_source (p, "s16", "s2");
+  t1 = oj_program_add_temporary (p, "s16", "t1");
+  offset = oj_program_add_constant (p, "s16", 1, "offset");
+  shift = oj_program_add_constant (p, "s16", 1, "shift");
+
+  oj_program_append (p, "add_s16", t1, s1, s2);
+  oj_program_append (p, "add_s16", t1, t1, offset);
+  oj_program_append (p, "rshift_s16", d1, t1, shift);
+
+  ex = oj_executor_new (p);
+
+  oj_executor_set_n (ex, N);
+  oj_executor_set_array (ex, s1, src1);
+  oj_executor_set_array (ex, s2, src2);
+  oj_executor_set_array (ex, d1, dest);
+
+  if (0) {
+    for(i=0;i<N;i++){
+      src1[i] = rand()&0xf;
+      src2[i] = rand()&0xf;
+    }
 
-  oj_program_append (p, "add_s16", d1, s1, s2);
+    oj_executor_emulate (ex);
 
-  oj_program_output_mmx (p);
+    for(i=0;i<N;i++){
+      printf("  %4d %4d %4d %4d\n", src1[i], src2[i], dest[i],
+          (src1[i] + src2[i] + 1)>>1);
+    }
+  } else {
+    oj_program_compile_x86 (p);
+  }
 
   return 0;
 }
diff --git a/examples/jit/ojopcodes.c b/examples/jit/ojopcodes.c
index f3d55b8..be65e55 100644
--- a/examples/jit/ojopcodes.c
+++ b/examples/jit/ojopcodes.c
@@ -52,33 +52,33 @@ oj_opcode_find_by_name (const char *name)
 }
 
 static void
-add_s16 (OJState *state, void *user)
+add_s16 (OJExecutor *ex, void *user)
 {
-  state->args[0] = (int16_t)(state->args[1] + state->args[2]);
+  ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 + ex->args[2]->s16);
 }
 
 static void
-sub_s16 (OJState *state, void *user)
+sub_s16 (OJExecutor *ex, void *user)
 {
-  state->args[0] = (int16_t)(state->args[1] - state->args[2]);
+  ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 - ex->args[2]->s16);
 }
 
 static void
-mul_s16 (OJState *state, void *user)
+mul_s16 (OJExecutor *ex, void *user)
 {
-  state->args[0] = (int16_t)(state->args[1] * state->args[2]);
+  ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 * ex->args[2]->s16);
 }
 
 static void
-lshift_s16 (OJState *state, void *user)
+lshift_s16 (OJExecutor *ex, void *user)
 {
-  state->args[0] = (int16_t)(state->args[1] << state->args[2]);
+  ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 << ex->args[2]->s16);
 }
 
 static void
-rshift_s16 (OJState *state, void *user)
+rshift_s16 (OJExecutor *ex, void *user)
 {
-  state->args[0] = (int16_t)(state->args[1] >> state->args[2]);
+  ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 >> ex->args[2]->s16);
 }
 
 void
diff --git a/examples/jit/ojprogram-x86.c b/examples/jit/ojprogram-x86.c
index 64083d6..7df11b6 100644
--- a/examples/jit/ojprogram-x86.c
+++ b/examples/jit/ojprogram-x86.c
@@ -9,6 +9,7 @@
 #include "ojprogram.h"
 
 
+#if 0
 void
 emit (unsigned int x)
 {
@@ -116,4 +117,337 @@ oj_program_output_mmx (OJProgram *program)
   g_print("  pop %%ebp\n");
   g_print("  ret\n");
 }
+#endif
+
+static const char *x86_regs[] = { "eax", "ecx", "edx", "ebx",
+  "esp", "ebp", "esi", "edi" };
+
+void oj_program_rewrite_vars (OJProgram *program);
+void oj_program_allocate_regs (OJProgram *program);
+void oj_program_dump (OJProgram *program);
+
+void
+oj_program_compile_x86 (OJProgram *program)
+{
+  int j;
+  int k;
+  OJInstruction *insn;
+  OJOpcode *opcode;
+  OJVariable *args[10];
+
+  oj_program_rewrite_vars (program);
+  oj_program_dump (program);
+
+  printf("# n_insns %d\n", program->n_insns);
+  g_print("  push %%ebp\n");
+  g_print("  movl 0x8(%%esp), %%ebp\n");
+
+  g_print("  movl 0x%02x(%%ebp), %%ecx\n", (int)G_STRUCT_OFFSET(OJExecutor,n));
+  g_print("  movl %%ecx, 0x%02x(%%ebp)\n", (int)G_STRUCT_OFFSET(OJExecutor,counter));
+  g_print("  testl %%ecx, %%ecx\n");
+  g_print("  jeq 2f\n");
+  g_print("1:\n");
+
+  for(j=0;j<program->n_insns;j++){
+    insn = program->insns + j;
+    opcode = insn->opcode;
+
+    printf("# %d: %s\n", j, insn->opcode->name);
+
+    /* set up args */
+    for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+      args[k] = program->vars + insn->args[k];
+
+      switch (args[k]->vartype) {
+        case OJ_VAR_TYPE_SRC:
+          g_print("  movl 0x%02x(%%ebp), %%esi\n",
+              (int)G_STRUCT_OFFSET(OJExecutor, arrays[k]));
+          g_print("  movw 0(%%esi), %%%s\n", x86_regs[k]);
+          break;
+        case OJ_VAR_TYPE_CONST:
+          g_print("  movl $%d, %%%s\n", args[k]->s16, x86_regs[k]);
+          break;
+        case OJ_VAR_TYPE_TEMP:
+          g_print("  movw temp, %%%s\n", x86_regs[k]);
+          break;
+        default:
+          break;
+      }
+    }
+
+    //opcode->emulate (ex, opcode->emulate_user);
+    printf("emit: %s\n", opcode->name);
+
+    for(k=0;k<opcode->n_dest;k++){
+      args[k] = program->vars + insn->args[k];
+
+      switch (args[k]->vartype) {
+        case OJ_VAR_TYPE_DEST:
+          g_print("  movl 0x%02x(%%ebp), %%esi\n",
+              (int)G_STRUCT_OFFSET(OJExecutor, arrays[k]));
+          g_print("  movw %%%s, 0(%%esi)\n", x86_regs[k]);
+          break;
+        case OJ_VAR_TYPE_TEMP:
+          g_print("  movw %%%s, temp\n", x86_regs[k]);
+          break;
+        default:
+          break;
+      }
+    }
+  }
+
+  g_print("  decl 0x%02x(%%ebp)\n", (int)G_STRUCT_OFFSET(OJExecutor,counter));
+  g_print("  jne 1b\n");
+  g_print("2:\n");
+
+  g_print("  pop %%ebp\n");
+  g_print("  ret\n");
+}
+
+
+static int
+oj_program_get_reg (OJProgram *program, int insn, int var)
+{
+  int i;
+
+  for(i=0;i<program->n_regs;i++) {
+    if (program->regs[i].var == var && !program->regs[i].retired) {
+      program->regs[i].last_use = insn;
+      return i;
+    }
+  }
+
+  program->regs[i].var = var;
+  program->regs[i].first_use = insn;
+  program->regs[i].last_use = insn;
+
+  program->n_regs++;
+
+  return i;
+}
+
+static void
+oj_program_retire_reg (OJProgram *program, int var)
+{
+  int i;
+
+  for(i=0;i<program->n_regs;i++) {
+    if (program->regs[i].var == var && !program->regs[i].retired) {
+      program->regs[i].retired = TRUE;
+      return;
+    }
+  }
+}
+
+void
+oj_program_allocate_regs (OJProgram *program)
+{
+  int i;
+  int j;
+  int k;
+  OJInstruction *insn;
+  OJOpcode *opcode;
+  OJVariable *args[10];
+  int alloc[8] = { 0, 0, 0, 0, 1, 1, 1, 0 };
+
+  for(j=0;j<program->n_insns;j++){
+    insn = program->insns + j;
+    opcode = insn->opcode;
+
+    /* set up args */
+    for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+      args[k] = program->vars + insn->args[k];
+
+      oj_program_get_reg (program, j, insn->args[k]);
+    }
+
+    for(k=0;k<opcode->n_dest;k++){
+      args[k] = program->vars + insn->args[k];
+
+      oj_program_retire_reg (program, insn->args[k]);
+      oj_program_get_reg (program, j, insn->args[k]);
+    }
+  }
+
+  for(j=0;j<program->n_insns;j++){
+    for(i=0;i<program->n_regs;i++){
+      if (program->regs[i].first_use == j) {
+        for(k=0;k<8;k++){
+          if (!alloc[k]) {
+            program->regs[i].alloc = k;
+            alloc[k] = 1;
+            break;
+          }
+        }
+        if (k==8) {
+          g_print("register overflow\n");
+        }
+      }
+    }
+    for(i=0;i<program->n_regs;i++){
+      if (program->regs[i].last_use == j) {
+        alloc[program->regs[i].alloc] = 0;
+      }
+    }
+  }
+
+  for(i=0;i<program->n_regs;i++){
+    g_print("%2d: %2d %2d %2d %d %s\n",
+        i, program->regs[i].var,
+        program->regs[i].first_use,
+        program->regs[i].last_use,
+        program->regs[i].retired,
+        x86_regs[program->regs[i].alloc]);
+  }
+
+}
+
+
+void
+oj_program_rewrite_vars (OJProgram *program)
+{
+  int j;
+  int k;
+  OJInstruction *insn;
+  OJOpcode *opcode;
+  int var;
+  int actual_var;
+
+  for(j=0;j<program->n_insns;j++){
+    insn = program->insns + j;
+    opcode = insn->opcode;
+
+    /* set up args */
+    for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+      var = insn->args[k];
+      if (program->vars[var].vartype == OJ_VAR_TYPE_DEST) {
+        g_print("ERROR: using dest var as source\n");
+      }
+
+      actual_var = var;
+      if (program->vars[var].replaced) {
+        actual_var = program->vars[var].replacement;
+        insn->args[k] = actual_var;
+      }
+
+      if (!program->vars[var].used) {
+        if (program->vars[var].vartype == OJ_VAR_TYPE_TEMP) {
+          g_print("ERROR: using uninitialized temp var\n");
+        }
+        program->vars[var].used = TRUE;
+        program->vars[var].first_use = j;
+      }
+      program->vars[var].last_use = j;
+    }
+
+    for(k=0;k<opcode->n_dest;k++){
+      var = insn->args[k];
+
+      if (program->vars[var].vartype == OJ_VAR_TYPE_SRC) {
+        g_print("ERROR: using src var as dest\n");
+      }
+      if (program->vars[var].vartype == OJ_VAR_TYPE_CONST) {
+        g_print("ERROR: using const var as dest\n");
+      }
+      if (program->vars[var].vartype == OJ_VAR_TYPE_PARAM) {
+        g_print("ERROR: using param var as dest\n");
+      }
+
+      actual_var = var;
+      if (program->vars[var].replaced) {
+        actual_var = program->vars[var].replacement;
+        insn->args[k] = actual_var;
+      }
+
+      if (!program->vars[var].used) {
+        program->vars[actual_var].used = TRUE;
+        program->vars[actual_var].first_use = j;
+      } else {
+        if (program->vars[var].vartype == OJ_VAR_TYPE_DEST) {
+          g_print("ERROR: writing dest more than once\n");
+        }
+        if (program->vars[var].vartype == OJ_VAR_TYPE_TEMP) {
+          actual_var = oj_program_dup_temporary (program, var, j);
+          program->vars[var].replaced = TRUE;
+          program->vars[var].replacement = actual_var;
+          insn->args[k] = actual_var;
+          program->vars[actual_var].used = TRUE;
+          program->vars[actual_var].first_use = j;
+        }
+      }
+      program->vars[actual_var].last_use = j;
+    }
+  }
+
+#if 0
+  for(j=0;j<program->n_insns;j++){
+    for(i=0;i<program->n_regs;i++){
+      if (program->regs[i].first_use == j) {
+        for(k=0;k<8;k++){
+          if (!alloc[k]) {
+            program->regs[i].alloc = k;
+            alloc[k] = 1;
+            break;
+          }
+        }
+        if (k==8) {
+          g_print("register overflow\n");
+        }
+      }
+    }
+    for(i=0;i<program->n_regs;i++){
+      if (program->regs[i].last_use == j) {
+        alloc[program->regs[i].alloc] = 0;
+      }
+    }
+  }
+
+  for(i=0;i<program->n_regs;i++){
+    g_print("%2d: %2d %2d %2d %d %s\n",
+        i, program->regs[i].var,
+        program->regs[i].first_use,
+        program->regs[i].last_use,
+        program->regs[i].retired,
+        x86_regs[program->regs[i].alloc]);
+  }
+#endif
+
+}
+
+void
+oj_program_dump (OJProgram *program)
+{
+  int i;
+  int j;
+  OJOpcode *opcode;
+  OJInstruction *insn;
+
+  for(i=0;i<program->n_insns;i++){
+    insn = program->insns + i;
+    opcode = insn->opcode;
+
+    g_print("insn: %d\n", i);
+    g_print("  opcode: %s\n", opcode->name);
+
+    for(j=0;j<opcode->n_dest;j++){
+      g_print("  dest%d: %d %s\n", j, insn->args[j],
+          program->vars[insn->args[j]].name);
+    }
+    for(j=0;j<opcode->n_src;j++){
+      g_print("  src%d: %d %s\n", j, insn->args[opcode->n_dest + j],
+          program->vars[insn->args[opcode->n_dest + j]].name);
+    }
+
+    g_print("\n");
+  }
+
+  for(i=0;i<program->n_vars;i++){
+    g_print("var: %d %s\n", i, program->vars[i].name);
+    g_print("first_use: %d\n", program->vars[i].first_use);
+    g_print("last_use: %d\n", program->vars[i].last_use);
+
+    g_print("\n");
+  }
+
+}
 
diff --git a/examples/jit/ojprogram.c b/examples/jit/ojprogram.c
index 44cbea3..6699c6e 100644
--- a/examples/jit/ojprogram.c
+++ b/examples/jit/ojprogram.c
@@ -18,46 +18,96 @@ oj_program_new (void)
 }
 
 int
-oj_program_add_temporary (OJProgram *program, OJType *type)
+oj_program_add_temporary (OJProgram *program, const char *type, const char *name)
 {
+  int i = program->n_vars;
 
-  return 0;
+  program->vars[i].vartype = OJ_VAR_TYPE_TEMP;
+  program->vars[i].type = oj_type_get(type);
+  program->vars[i].name = strdup(name);
+  program->n_vars++;
+
+  return i;
 }
 
 int
-oj_program_add_source (OJProgram *program, const char *type)
+oj_program_dup_temporary (OJProgram *program, int var, int j)
 {
+  int i = program->n_vars;
 
-  return 0;
+  program->vars[i].vartype = OJ_VAR_TYPE_TEMP;
+  program->vars[i].type = program->vars[var].type;
+  program->vars[i].name = g_strdup_printf("%s.dup%d",
+      program->vars[var].name, j);
+  program->n_vars++;
+
+  return i;
 }
 
 int
-oj_program_add_destination (OJProgram *program, const char *type)
+oj_program_add_source (OJProgram *program, const char *type, const char *name)
 {
+  int i = program->n_vars;
 
-  return 0;
+  program->vars[i].vartype = OJ_VAR_TYPE_SRC;
+  program->vars[i].type = oj_type_get(type);
+  program->vars[i].name = strdup(name);
+  program->n_vars++;
+
+  return i;
 }
 
 int
-oj_program_add_constant (OJProgram *program, OJType *type, int value)
+oj_program_add_destination (OJProgram *program, const char *type, const char *name)
 {
+  int i = program->n_vars;
 
-  return 0;
+  program->vars[i].vartype = OJ_VAR_TYPE_DEST;
+  program->vars[i].type = oj_type_get(type);
+  program->vars[i].name = strdup(name);
+  program->n_vars++;
+
+  return i;
 }
 
 int
-oj_program_add_parameter (OJProgram *program, OJType *type, int value)
+oj_program_add_constant (OJProgram *program, const char *type, int value, const char *name)
+{
+  int i = program->n_vars;
+
+  program->vars[i].vartype = OJ_VAR_TYPE_CONST;
+  program->vars[i].type = oj_type_get(type);
+  program->vars[i].s16 = value;
+  program->vars[i].name = strdup(name);
+  program->n_vars++;
+
+  return i;
+}
+
+int
+oj_program_add_parameter (OJProgram *program, OJType *type, int value, const char *name)
 {
 
   return 0;
 }
 
 void
-oj_program_append (OJProgram *program, const char *opcode, int arg0,
+oj_program_append (OJProgram *program, const char *name, int arg0,
     int arg1, int arg2)
 {
+  OJInstruction *insn;
 
+  insn = program->insns + program->n_insns;
 
+  insn->opcode = oj_opcode_find_by_name (name);
+  if (!insn->opcode) {
+    printf("unknown opcode: %s\n", name);
+  }
+  insn->args[0] = arg0;
+  insn->args[1] = arg1;
+  insn->args[2] = arg2;
+  
+  program->n_insns++;
 }
 
 
@@ -96,3 +146,94 @@ oj_type_register (const char *name, int size)
 }
 
 
+
+OJExecutor *
+oj_executor_new (OJProgram *program)
+{
+  OJExecutor *ex;
+
+  ex = g_malloc0(sizeof(OJExecutor));
+
+  ex->program = program;
+
+  memcpy (ex->vars, program->vars, 10*sizeof(OJVariable));
+
+  return ex;
+}
+
+void
+oj_executor_free (OJExecutor *ex)
+{
+  g_free (ex);
+}
+
+void
+oj_executor_run (OJExecutor *ex)
+{
+
+
+}
+
+void
+oj_executor_set_array (OJExecutor *ex, int var, void *ptr)
+{
+  ex->arrays[var] = ptr;
+}
+
+void
+oj_executor_set_n (OJExecutor *ex, int n)
+{
+  ex->n = n;
+}
+
+void
+oj_executor_emulate (OJExecutor *ex)
+{
+  int i;
+  int j;
+  int k;
+  OJProgram *program = ex->program;
+  OJInstruction *insn;
+  OJOpcode *opcode;
+
+  printf("n %d\n", ex->n);
+  printf("n_insns %d\n", program->n_insns);
+
+  for(i=0;i<ex->n;i++){
+    for(j=0;j<program->n_insns;j++){
+      insn = program->insns + j;
+      opcode = insn->opcode;
+
+      printf("%d: %s\n", j, insn->opcode->name);
+
+      /* set up args */
+      for(k=0;k<opcode->n_src + opcode->n_dest;k++){
+        ex->args[k] = ex->vars + insn->args[k];
+
+        printf("setting up arg %d as var %d vartype %d\n",
+            k, insn->args[k], ex->args[k]->vartype);
+
+        if (ex->args[k]->vartype == OJ_VAR_TYPE_SRC) {
+          void *ptr = ex->arrays[insn->args[k]] + 2*i;
+
+          printf("load %p\n", ptr);
+          ex->args[k]->s16 = *(int16_t *)ptr;
+        }
+      }
+
+      opcode->emulate (ex, opcode->emulate_user);
+      printf("emulate: %d %d %d\n", ex->args[0]->s16,
+          ex->args[1]->s16, ex->args[2]->s16);
+
+      for(k=0;k<opcode->n_src + opcode->n_dest;k++){
+        if (ex->args[k]->vartype == OJ_VAR_TYPE_DEST) {
+          void *ptr = ex->arrays[insn->args[k]] + 2*i;
+
+          printf("store %p\n", ptr);
+          *(int16_t *)ptr = ex->args[k]->s16;
+        }
+      }
+    }
+  }
+}
+
diff --git a/examples/jit/ojprogram.h b/examples/jit/ojprogram.h
index effcb65..c825563 100644
--- a/examples/jit/ojprogram.h
+++ b/examples/jit/ojprogram.h
@@ -4,17 +4,57 @@
 
 #include <glib.h>
 
+typedef struct _OJType OJType;
+typedef struct _OJExecutor OJExecutor;
+typedef struct _OJVariable OJVariable;
+typedef struct _OJOpcode OJOpcode;
+typedef struct _OJArgument OJArgument;
+typedef struct _OJInstruction OJInstruction;
+typedef struct _OJProgram OJProgram;
+typedef struct _OJRegister OJRegister;
+
+typedef void (*OJOpcodeEmulateFunc)(OJExecutor *ex, void *user);
+
+struct _OJType {
+  char *name;
+  int size;
+};
 
-typedef struct _OJVariable {
+typedef enum {
+  OJ_VAR_TYPE_TEMP,
+  OJ_VAR_TYPE_SRC,
+  OJ_VAR_TYPE_DEST,
+  OJ_VAR_TYPE_CONST,
+  OJ_VAR_TYPE_PARAM
+} OJVarType;
+
+struct _OJVariable {
   char *name;
-} OJVariable;
 
-typedef struct _OJType {
+  OJType *type;
+  OJVarType vartype;
+
+  int used;
+  int first_use;
+  int last_use;
+  int replaced;
+  int replacement;
+
+  int16_t s16;
+};
+
+
+struct _OJOpcode {
   char *name;
-  int size;
-} OJType;
+  int n_src;
+  int n_dest;
+  OJType *arg_types[10];
 
-typedef struct _OJArgument {
+  OJOpcodeEmulateFunc emulate;
+  void *emulate_user;
+};
+
+struct _OJArgument {
   OJVariable *var;
   int is_indirect;
   int is_indexed;
@@ -23,70 +63,76 @@ typedef struct _OJArgument {
   int type; // remove
   int index; // remove
   int offset;
-} OJArgument;
+};
+
+struct _OJInstruction {
+  OJOpcode *opcode;
+  int args[3];
+};
 
-typedef struct _OJInstruction {
-  int opcode;
+struct _OJRegister {
+  int var;
 
-  OJArgument args[3];
-} OJInstruction;
+  int first_use;
+  int last_use;
+  int retired;
 
-typedef struct _OJProgram {
+  int alloc;
+};
+
+struct _OJProgram {
   OJInstruction insns[100];
   int n_insns;
 
   OJVariable vars[100];
   int n_vars;
 
-  /* parsing state */
-  char *s;
-  char *error;
-
   OJInstruction *insn;
 
-}OJProgram;
-
-typedef struct _OJState {
-  int index;
-
-  int args[4];
+  OJRegister regs[100];
+  int n_regs;
+};
 
-}OJState;
+struct _OJExecutor {
+  OJProgram *program;
+  int n;
+  int counter;
 
-typedef void (*OJOpcodeEmulateFunc)(OJState *state, void *user);
-
-typedef struct _OJOpcode {
-  char *name;
-  int n_src;
-  int n_dest;
-  OJType *arg_types[10];
+  void *arrays[10];
 
-  OJOpcodeEmulateFunc emulate;
-  void *emulate_user;
-} OJOpcode;
+  OJVariable vars[10];
+  OJVariable *args[4];
 
+};
 
 OJProgram * oj_program_new (void);
-int oj_opcode_lookup (const char *s, int len);
+OJOpcode * oj_opcode_find_by_name (const char *name);
+void oj_opcode_init (void);
 
 void oj_program_append (OJProgram *p, const char *opcode, int arg0, int arg1, int arg2);
 
-void oj_program_output_mmx (OJProgram *p);
+void oj_program_compile_x86 (OJProgram *p);
 void oj_program_free (OJProgram *program);
 
-int oj_program_add_temporary (OJProgram *program, OJType *type);
-int oj_program_add_source (OJProgram *program, const char *type);
-int oj_program_add_destination (OJProgram *program, const char *type);
-int oj_program_add_constant (OJProgram *program, OJType *type, int value);
-int oj_program_add_parameter (OJProgram *program, OJType *type, int value);
+int oj_program_add_temporary (OJProgram *program, const char *type, const char *name);
+int oj_program_dup_temporary (OJProgram *program, int i, int j);
+int oj_program_add_source (OJProgram *program, const char *type, const char *name);
+int oj_program_add_destination (OJProgram *program, const char *type, const char *name);
+int oj_program_add_constant (OJProgram *program, const char *type, int value, const char *name);
 void oj_program_append (OJProgram *program, const char *opcode, int arg0,
     int arg1, int arg2);
 
 
-
 OJType * oj_type_get (const char *name);
 void oj_type_register (const char *name, int size);
 
+OJExecutor * oj_executor_new (OJProgram *program);
+void oj_executor_free (OJExecutor *ex);
+void oj_executor_set_array (OJExecutor *ex, int var, void *ptr);
+void oj_executor_set_n (OJExecutor *ex, int n);
+void oj_executor_emulate (OJExecutor *ex);
+
+
 
 #endif
 


More information about the Liboil-commit mailing list