summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2008-05-12 16:45:56 -0700
committerDavid Schleef <ds@ginger.bigkitten.com>2008-05-12 16:45:56 -0700
commit0dd84b6abc37193e0186360ae2a10d52eb78b544 (patch)
treee4a0fdba9af80e47446c8e7882a54f747f88ff3c /examples
parentb3e5b417e8c727846d9ae5a7791b5ddcdc05dc81 (diff)
downloadliboil-0dd84b6abc37193e0186360ae2a10d52eb78b544.tar.gz
jit hacking
Diffstat (limited to 'examples')
-rw-r--r--examples/jit/Makefile.am3
-rw-r--r--examples/jit/jit.c15
-rw-r--r--examples/jit/ojopcodes.c94
-rw-r--r--examples/jit/ojprogram.c190
-rw-r--r--examples/jit/ojprogram.h39
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