summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2007-12-27 17:22:14 -0800
committerDavid Schleef <ds@ginger.bigkitten.com>2007-12-27 17:22:14 -0800
commitd90d3298c4d01e68e6ee6902785acaa2b0089044 (patch)
treeea757df8dfaefab347751e6ad0ae33ddb90b26b5 /examples
parent3a6bcdb7221129b306f41bd4b421d28030b77614 (diff)
Add some experimental JIT code
Diffstat (limited to 'examples')
-rw-r--r--examples/.gitignore1
-rw-r--r--examples/jit/Makefile.am2
-rw-r--r--examples/jit/jit.c345
-rw-r--r--examples/jit/ojprogram-x86.c119
-rw-r--r--examples/jit/ojprogram.c196
-rw-r--r--examples/jit/ojprogram.h57
6 files changed, 376 insertions, 344 deletions
diff --git a/examples/.gitignore b/examples/.gitignore
index 37a77f2..bd7dfea 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -1,6 +1,7 @@
audioresample/test_functable1
example1
huffman/huffman_test
+jit/jit
jpeg/jpeg_rgb_test
jpeg/jpeg_test
md5/md5sum
diff --git a/examples/jit/Makefile.am b/examples/jit/Makefile.am
index 56b144b..3c7dd5b 100644
--- a/examples/jit/Makefile.am
+++ b/examples/jit/Makefile.am
@@ -6,3 +6,5 @@ noinst_PROGRAMS = jit
AM_LDFLAGS = $(LIBOIL_LIBS) $(GLIB_LIBS)
AM_CFLAGS = $(LIBOIL_CFLAGS) $(GLIB_CFLAGS)
+jit_SOURCES = jit.c ojprogram.c ojprogram-x86.c
+
diff --git a/examples/jit/jit.c b/examples/jit/jit.c
index be2bc9c..6debf54 100644
--- a/examples/jit/jit.c
+++ b/examples/jit/jit.c
@@ -6,350 +6,7 @@
#include <string.h>
#include <stdlib.h>
-
-void
-stuff (void *d, void *s1, void *s2)
-{
-
- __asm__ __volatile__ (
- " movq 0(%[s1]), %%mm0 \n"
- " movq 0(%[s2]), %%mm1 \n"
- " paddw %%mm1, %%mm0 \n"
- " movq %%mm0, 0(%[d]) \n"
- " emms \n"
- : [d] "+r" (d), [s1] "+r" (s1), [s2] "+r" (s2));
-}
-
-
-typedef struct _OJArgument {
- int type;
- int index;
- int offset;
-} OJArgument;
-
-typedef struct _OJInstruction {
- int opcode;
-
- OJArgument args[3];
-} OJInstruction;
-
-typedef struct _OJRegister {
- int type;
-
- int index;
-}OJRegister;
-
-typedef struct _OJProgram {
- OJInstruction insns[100];
- int n_insns;
-
- /* parsing state */
- char *s;
- char *error;
-
- OJInstruction *insn;
-
-}OJProgram;
-
-typedef struct _OJOpcode {
- char *name;
- int n_args;
-} OJOpcode;
-
-
-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)
-{
- OJProgram *p;
- p = g_malloc0(sizeof(OJProgram));
- return p;
-}
-
-int
-oj_opcode_lookup (const char *s, int len)
-{
- 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;
-}
-
-static gboolean
-get_opcode (OJProgram *p)
-{
- 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;
-}
-
-static gboolean
-get_arg (OJProgram *p, int i)
-{
- 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;
-}
-
-static gboolean
-skip_comma (OJProgram *p)
-{
- char *s;
-
- if (p->error) return FALSE;
-
- g_print("looking for comma at \"%s\"\n", p->s);
-
- 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++;
-
- p->s = s;
- return TRUE;
-}
-
-void
-oj_program_parse (OJProgram *p, const char *program)
-{
- 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);
-
- 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);
- }
- }
-
- 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;
- }
-
- p->n_insns++;
- }
- g_strfreev (lines);
-}
-
-void
-emit (unsigned int x)
-{
- g_print ("%02x ", x);
-}
-
-void
-emit_modrm (OJArgument *reg, OJArgument *regmem)
-{
- int bits_mod;
- int bits_rm;
- int bits_reg;
-
- if (regmem->type != ARG_REG) {
- if (regmem->offset == 0) {
- bits_mod = 0;
- bits_rm = regmem->index;
- bits_reg = reg->index;
- emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
- } else {
- if (regmem->offset <= 127 && regmem->offset >= -128) {
- bits_mod = 1;
- bits_rm = regmem->index;
- bits_reg = reg->index;
- emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
- emit (regmem->offset);
- } else {
- bits_mod = 2;
- bits_rm = regmem->index;
- bits_reg = reg->index;
- emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
- emit ((regmem->offset>>0) & 0xff);
- emit ((regmem->offset>>8) & 0xff);
- emit ((regmem->offset>>16) & 0xff);
- emit ((regmem->offset>>24) & 0xff);
- }
- }
- } else {
- bits_mod = 3;
- bits_rm = regmem->index;
- bits_reg = reg->index;
- emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
- }
-
-}
-
-void
-oj_program_output_mmx (OJProgram *program)
-{
- int i;
- char *dest_regs[] = { "error", "eax", "error", "error" };
- char *src_regs[] = { "error", "ecx", "edx", "error" };
- char *r_regs[] = { "mm0", "mm1", "mm2", "mm3" };
- OJInstruction *insn;
-
- g_print(" push %%ebp\n");
- g_print(" movl %%esp, %%ebp\n");
- g_print(" movl 0x8(%%ebp), %%%s\n", dest_regs[1]);
- g_print(" movl 0xc(%%ebp), %%%s\n", src_regs[1]);
- g_print(" movl 0x10(%%ebp), %%%s\n", src_regs[2]);
-
- for(i=0;i<program->n_insns;i++){
- insn = program->insns + i;
- switch (insn->opcode) {
- case 0:
- g_print (" movq %d(%%%s), %%%s\n",
- insn->args[1].offset,
- src_regs[insn->args[1].index],
- r_regs[insn->args[0].index]);
- emit (0x0f);
- emit (0x6f);
- emit_modrm (insn->args + 0, insn->args + 1);
- g_print ("\n");
- break;
- case 1:
- g_print (" movq %%%s, %d(%%%s)\n",
- r_regs[insn->args[1].index],
- insn->args[0].offset,
- dest_regs[insn->args[0].index]);
- emit (0x0f);
- emit (0x7f);
- emit_modrm (insn->args + 1, insn->args + 0);
- g_print ("\n");
- break;
- case 2:
- g_print (" movq %%%s, %%%s\n",
- r_regs[insn->args[2].index],
- r_regs[insn->args[0].index]);
- emit (0x0f);
- emit (0x6f);
- emit_modrm (insn->args + 0, insn->args + 1);
- g_print ("\n");
- g_print (" paddw %%%s, %%%s\n",
- r_regs[insn->args[1].index],
- r_regs[insn->args[0].index]);
- emit (0x0f);
- emit (0xfd);
- emit_modrm (insn->args + 0, insn->args + 1);
- g_print ("\n");
- break;
- }
- }
-
- g_print(" emms\n");
- g_print(" pop %%ebp\n");
- g_print(" ret\n");
-}
-
+#include "ojprogram.h"
const char *program =
"load r0, s1\n"
diff --git a/examples/jit/ojprogram-x86.c b/examples/jit/ojprogram-x86.c
new file mode 100644
index 0000000..64083d6
--- /dev/null
+++ b/examples/jit/ojprogram-x86.c
@@ -0,0 +1,119 @@
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ojprogram.h"
+
+
+void
+emit (unsigned int x)
+{
+ g_print ("%02x ", x);
+}
+
+void
+emit_modrm (OJArgument *reg, OJArgument *regmem)
+{
+ int bits_mod;
+ int bits_rm;
+ int bits_reg;
+
+ if (regmem->is_indirect) {
+ if (regmem->offset == 0) {
+ bits_mod = 0;
+ bits_rm = regmem->index;
+ bits_reg = reg->index;
+ emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
+ } else {
+ if (regmem->offset <= 127 && regmem->offset >= -128) {
+ bits_mod = 1;
+ bits_rm = regmem->index;
+ bits_reg = reg->index;
+ emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
+ emit (regmem->offset);
+ } else {
+ bits_mod = 2;
+ bits_rm = regmem->index;
+ bits_reg = reg->index;
+ emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
+ emit ((regmem->offset>>0) & 0xff);
+ emit ((regmem->offset>>8) & 0xff);
+ emit ((regmem->offset>>16) & 0xff);
+ emit ((regmem->offset>>24) & 0xff);
+ }
+ }
+ } else {
+ bits_mod = 3;
+ bits_rm = regmem->index;
+ bits_reg = reg->index;
+ emit ((bits_reg << 5) | (bits_mod << 3) | (bits_rm));
+ }
+
+}
+
+void
+oj_program_output_mmx (OJProgram *program)
+{
+ int i;
+ char *dest_regs[] = { "error", "eax", "error", "error" };
+ char *src_regs[] = { "error", "ecx", "edx", "error" };
+ char *r_regs[] = { "mm0", "mm1", "mm2", "mm3" };
+ OJInstruction *insn;
+
+ g_print(" push %%ebp\n");
+ g_print(" movl %%esp, %%ebp\n");
+ g_print(" movl 0x8(%%ebp), %%%s\n", dest_regs[1]);
+ g_print(" movl 0xc(%%ebp), %%%s\n", src_regs[1]);
+ g_print(" movl 0x10(%%ebp), %%%s\n", src_regs[2]);
+
+ for(i=0;i<program->n_insns;i++){
+ insn = program->insns + i;
+ switch (insn->opcode) {
+ case 0:
+ g_print (" movq %d(%%%s), %%%s\n",
+ insn->args[1].offset,
+ src_regs[insn->args[1].index],
+ r_regs[insn->args[0].index]);
+ emit (0x0f);
+ emit (0x6f);
+ emit_modrm (insn->args + 0, insn->args + 1);
+ g_print ("\n");
+ break;
+ case 1:
+ g_print (" movq %%%s, %d(%%%s)\n",
+ r_regs[insn->args[1].index],
+ insn->args[0].offset,
+ dest_regs[insn->args[0].index]);
+ emit (0x0f);
+ emit (0x7f);
+ emit_modrm (insn->args + 1, insn->args + 0);
+ g_print ("\n");
+ break;
+ case 2:
+ g_print (" movq %%%s, %%%s\n",
+ r_regs[insn->args[2].index],
+ r_regs[insn->args[0].index]);
+ emit (0x0f);
+ emit (0x6f);
+ emit_modrm (insn->args + 0, insn->args + 1);
+ g_print ("\n");
+ g_print (" paddw %%%s, %%%s\n",
+ r_regs[insn->args[1].index],
+ r_regs[insn->args[0].index]);
+ emit (0x0f);
+ emit (0xfd);
+ emit_modrm (insn->args + 0, insn->args + 1);
+ g_print ("\n");
+ break;
+ }
+ }
+
+ g_print(" emms\n");
+ g_print(" pop %%ebp\n");
+ g_print(" ret\n");
+}
+
diff --git a/examples/jit/ojprogram.c b/examples/jit/ojprogram.c
new file mode 100644
index 0000000..aac03c8
--- /dev/null
+++ b/examples/jit/ojprogram.c
@@ -0,0 +1,196 @@
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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)
+{
+ OJProgram *p;
+ p = g_malloc0(sizeof(OJProgram));
+ return p;
+}
+
+int
+oj_opcode_lookup (const char *s, int len)
+{
+ 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;
+}
+
+static gboolean
+get_opcode (OJProgram *p)
+{
+ 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;
+}
+
+static gboolean
+get_arg (OJProgram *p, int i)
+{
+ 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;
+}
+
+static gboolean
+skip_comma (OJProgram *p)
+{
+ char *s;
+
+ if (p->error) return FALSE;
+
+ g_print("looking for comma at \"%s\"\n", p->s);
+
+ 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++;
+
+ p->s = s;
+ return TRUE;
+}
+
+void
+oj_program_parse (OJProgram *p, const char *program)
+{
+ 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);
+
+ 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);
+ }
+ }
+
+ 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;
+ }
+
+ p->n_insns++;
+ }
+ g_strfreev (lines);
+}
+
diff --git a/examples/jit/ojprogram.h b/examples/jit/ojprogram.h
new file mode 100644
index 0000000..db87814
--- /dev/null
+++ b/examples/jit/ojprogram.h
@@ -0,0 +1,57 @@
+
+#ifndef _OJ_PROGRAM_H_
+#define _OJ_PROGRAM_H_
+
+#include <glib.h>
+
+
+typedef struct _OJVariable {
+ char *name;
+} OJVariable;
+
+typedef struct _OJArgument {
+ OJVariable *var;
+ int is_indirect;
+ int is_indexed;
+ OJVariable *index_var;
+ int index_scale;
+ int type; // remove
+ int index; // remove
+ int offset;
+} OJArgument;
+
+typedef struct _OJInstruction {
+ int opcode;
+
+ OJArgument args[3];
+} OJInstruction;
+
+typedef 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 _OJOpcode {
+ char *name;
+ int n_args;
+} 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_output_mmx (OJProgram *p);
+void oj_program_free (OJProgram *program);
+
+#endif
+