diff options
author | David Schleef <ds@ginger.bigkitten.com> | 2008-05-12 16:45:56 -0700 |
---|---|---|
committer | David Schleef <ds@ginger.bigkitten.com> | 2008-05-12 16:45:56 -0700 |
commit | 0dd84b6abc37193e0186360ae2a10d52eb78b544 (patch) | |
tree | e4a0fdba9af80e47446c8e7882a54f747f88ff3c | |
parent | b3e5b417e8c727846d9ae5a7791b5ddcdc05dc81 (diff) | |
download | liboil-0dd84b6abc37193e0186360ae2a10d52eb78b544.tar.gz |
jit hacking
-rw-r--r-- | examples/jit/Makefile.am | 3 | ||||
-rw-r--r-- | examples/jit/jit.c | 15 | ||||
-rw-r--r-- | examples/jit/ojopcodes.c | 94 | ||||
-rw-r--r-- | examples/jit/ojprogram.c | 190 | ||||
-rw-r--r-- | examples/jit/ojprogram.h | 39 |
5 files changed, 187 insertions, 154 deletions
diff --git a/examples/jit/Makefile.am b/examples/jit/Makefile.am index d1c68ec..0a844a8 100644 --- a/examples/jit/Makefile.am +++ b/examples/jit/Makefile.am @@ -6,5 +6,6 @@ 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 6debf54..7ccb751 100644 --- a/examples/jit/jit.c +++ b/examples/jit/jit.c @@ -8,19 +8,20 @@ #include "ojprogram.h" -const char *program = -"load r0, s1\n" -"load r1, s2\n" -"add r2, r0, r1\n" -"store d1, r2\n"; - int main (int argc, char *argv[]) { OJProgram *p; + int s1, s2, d1; p = oj_program_new (); - oj_program_parse (p, program); + + d1 = oj_program_add_destination (p, "s16"); + s1 = oj_program_add_source (p, "s16"); + s2 = oj_program_add_source (p, "s16"); + + oj_program_append (p, "add_s16", d1, s1, s2); + oj_program_output_mmx (p); return 0; diff --git a/examples/jit/ojopcodes.c b/examples/jit/ojopcodes.c new file mode 100644 index 0000000..f3d55b8 --- /dev/null +++ b/examples/jit/ojopcodes.c @@ -0,0 +1,94 @@ + +#include "config.h" + +#include <glib.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "ojprogram.h" + + +static OJOpcode *opcode_list; +static int n_opcodes; +static int n_opcodes_alloc; + + + +void +oj_opcode_register (const char *name, int n_dest, int n_src, + OJOpcodeEmulateFunc emulate, void *user) +{ + OJOpcode *opcode; + + if (n_opcodes == n_opcodes_alloc) { + n_opcodes_alloc += 100; + opcode_list = realloc(opcode_list, sizeof(OJOpcode) * n_opcodes_alloc); + } + + opcode = opcode_list + n_opcodes; + + opcode->name = strdup (name); + opcode->n_src = n_src; + opcode->n_dest = n_dest; + opcode->emulate = emulate; + opcode->emulate_user = user; + + n_opcodes++; +} + +OJOpcode * +oj_opcode_find_by_name (const char *name) +{ + int i; + + for(i=0;i<n_opcodes;i++){ + if (!strcmp (name, opcode_list[i].name)) { + return opcode_list + i; + } + } + + return NULL; +} + +static void +add_s16 (OJState *state, void *user) +{ + state->args[0] = (int16_t)(state->args[1] + state->args[2]); +} + +static void +sub_s16 (OJState *state, void *user) +{ + state->args[0] = (int16_t)(state->args[1] - state->args[2]); +} + +static void +mul_s16 (OJState *state, void *user) +{ + state->args[0] = (int16_t)(state->args[1] * state->args[2]); +} + +static void +lshift_s16 (OJState *state, void *user) +{ + state->args[0] = (int16_t)(state->args[1] << state->args[2]); +} + +static void +rshift_s16 (OJState *state, void *user) +{ + state->args[0] = (int16_t)(state->args[1] >> state->args[2]); +} + +void +oj_opcode_init (void) +{ + oj_opcode_register("add_s16", 1, 2, add_s16, NULL); + oj_opcode_register("sub_s16", 1, 2, sub_s16, NULL); + oj_opcode_register("mul_s16", 1, 2, mul_s16, NULL); + oj_opcode_register("lshift_s16", 1, 2, lshift_s16, NULL); + oj_opcode_register("rshift_s16", 1, 2, rshift_s16, NULL); +} + + diff --git a/examples/jit/ojprogram.c b/examples/jit/ojprogram.c index aac03c8..44cbea3 100644 --- a/examples/jit/ojprogram.c +++ b/examples/jit/ojprogram.c @@ -9,18 +9,6 @@ #include "ojprogram.h" -const OJOpcode opcode_list[] = { - { "load", 2 }, - { "store", 2 }, - { "add", 3 } -}; -#define N_OPCODES 3 - -#define ARG_REG 0 -#define ARG_SRC 1 -#define ARG_DEST 2 - - OJProgram * oj_program_new (void) { @@ -30,167 +18,81 @@ oj_program_new (void) } int -oj_opcode_lookup (const char *s, int len) +oj_program_add_temporary (OJProgram *program, OJType *type) { - int i; - for(i=0;i<N_OPCODES;i++){ - if (strlen (opcode_list[i].name) != len) continue; - if (strncmp (opcode_list[i].name, s, len) == 0) { - return i; - } - } - return -1; + return 0; } -static gboolean -get_opcode (OJProgram *p) +int +oj_program_add_source (OJProgram *program, const char *type) { - char *s; - char *opcode; - int opcode_len; - int i; - - if (p->error) return FALSE; - - g_print("looking for opcode at \"%s\"\n", p->s); - - s = p->s; - while (g_ascii_isspace (s[0])) s++; - opcode = s; - while (g_ascii_isalnum (s[0])) s++; - opcode_len = s - opcode; - if (opcode_len == 0) { - p->error = g_strdup ("expected opcode"); - return FALSE; - } - - p->insn->opcode = oj_opcode_lookup (opcode, opcode_len); - - for(i=0;i<N_OPCODES;i++){ - if (strlen (opcode_list[i].name) != opcode_len) continue; - if (strncmp (opcode_list[i].name, opcode, opcode_len) == 0) { - break; - } - } - if (i == N_OPCODES) { - p->error = g_strdup ("unknown opcode"); - return FALSE; - } - - p->insn->opcode = i; - p->s = s; - return TRUE; + return 0; } -static gboolean -get_arg (OJProgram *p, int i) +int +oj_program_add_destination (OJProgram *program, const char *type) { - char *s; - char *end; - - if (p->error) return FALSE; - - g_print("looking for arg at \"%s\"\n", p->s); - - s = p->s; - while (g_ascii_isspace (s[0])) s++; - - switch (s[0]) { - case 'r': - p->insn->args[i].type = ARG_REG; - break; - case 's': - p->insn->args[i].type = ARG_SRC; - break; - case 'd': - p->insn->args[i].type = ARG_DEST; - break; - default: - p->s = s; - p->error = g_strdup ("expected argument"); - return FALSE; - } - s++; - p->insn->args[i].index = strtoul (s, &end, 10); - if (s == end) { - p->s = s; - p->error = strdup ("expected number"); - return FALSE; - } - - s = end; - - p->s = s; - return TRUE; + return 0; } -static gboolean -skip_comma (OJProgram *p) +int +oj_program_add_constant (OJProgram *program, OJType *type, int value) { - char *s; - if (p->error) return FALSE; - - g_print("looking for comma at \"%s\"\n", p->s); + return 0; +} - s = p->s; - while (g_ascii_isspace (s[0])) s++; - if (s[0] != ',') { - p->error = g_strdup ("expected comma"); - return FALSE; - } - s++; - while (g_ascii_isspace (s[0])) s++; +int +oj_program_add_parameter (OJProgram *program, OJType *type, int value) +{ - p->s = s; - return TRUE; + return 0; } void -oj_program_parse (OJProgram *p, const char *program) +oj_program_append (OJProgram *program, const char *opcode, int arg0, + int arg1, int arg2) { - char **lines; - char *line; - char *s; - int i; - lines = g_strsplit(program, "\n", 0); - for(i=0;lines[i];i++){ - p->insn = p->insns + p->n_insns; - line = lines[i]; - - s = line; +} - g_print("looking at \"%s\"\n", s); - while (g_ascii_isspace (s[0])) s++; - if (s[0] == 0 || s[0] == '#') continue; - p->s = s; - get_opcode (p); +OJType *types; +static int n_types; +static int n_alloc_types; - get_arg (p, 0); - if (opcode_list[p->insn->opcode].n_args >= 2) { - skip_comma (p); - get_arg (p, 1); - if (opcode_list[p->insn->opcode].n_args >= 3) { - skip_comma (p); - get_arg (p, 2); - } +OJType * +oj_type_get (const char *name) +{ + int i; + for(i=0;i<n_types;i++){ + if (!strcmp (types[i].name, name)) { + return types + i; } + } + return NULL; +} - if (p->error) { - g_print("error on line %d: %s at \"%s\"\n", i, p->error, p->s); - g_free(p->error); - p->error = NULL; - } +void +oj_type_register (const char *name, int size) +{ + OJType *type; - p->n_insns++; + if (n_types == n_alloc_types) { + n_alloc_types += 100; + types = realloc (types, sizeof(OJType) * n_alloc_types); } - g_strfreev (lines); + + type = types + n_types; + type->name = strdup (name); + type->size = size; + + n_types++; } + diff --git a/examples/jit/ojprogram.h b/examples/jit/ojprogram.h index db87814..effcb65 100644 --- a/examples/jit/ojprogram.h +++ b/examples/jit/ojprogram.h @@ -9,6 +9,11 @@ typedef struct _OJVariable { char *name; } OJVariable; +typedef struct _OJType { + char *name; + int size; +} OJType; + typedef struct _OJArgument { OJVariable *var; int is_indirect; @@ -41,17 +46,47 @@ typedef struct _OJProgram { }OJProgram; +typedef struct _OJState { + int index; + + int args[4]; + +}OJState; + +typedef void (*OJOpcodeEmulateFunc)(OJState *state, void *user); + typedef struct _OJOpcode { char *name; - int n_args; + int n_src; + int n_dest; + OJType *arg_types[10]; + + OJOpcodeEmulateFunc emulate; + void *emulate_user; } OJOpcode; OJProgram * oj_program_new (void); int oj_opcode_lookup (const char *s, int len); -void oj_program_parse (OJProgram *p, const char *program); + +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_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); +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); + + #endif |