[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