summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2008-05-15 00:30:59 -0700
committerDavid Schleef <ds@ginger.bigkitten.com>2008-05-15 00:30:59 -0700
commit1501bac739641b8a5bf91a16dae3a849f7544d33 (patch)
tree3c068889041ae2d581020fbe4ad9ab867efaf492 /examples
parent6d4c856e5b2ea343f90173a77b5de5153ce4fdcc (diff)
jit: code cleanup
Diffstat (limited to 'examples')
-rw-r--r--examples/jit/ojprogram-x86.c235
-rw-r--r--examples/jit/ojprogram.c112
-rw-r--r--examples/jit/ojprogram.h14
3 files changed, 176 insertions, 185 deletions
diff --git a/examples/jit/ojprogram-x86.c b/examples/jit/ojprogram-x86.c
index b3312ca..1911b9f 100644
--- a/examples/jit/ojprogram-x86.c
+++ b/examples/jit/ojprogram-x86.c
@@ -14,8 +14,6 @@
#define SIZE 65536
-#define X86_REG_BASE 8
-
void x86_emit_push (OJProgram *program, int size, int reg);
void x86_emit_pop (OJProgram *program, int size, int reg);
void x86_emit_mov_memoffset_reg (OJProgram *program, int size, int offset, int reg1, int reg2);
@@ -37,7 +35,7 @@ void x86_test (OJProgram *program);
void oj_program_dump_code (OJProgram *program);
enum {
- X86_EAX = X86_REG_BASE,
+ X86_EAX = OJ_GP_REG_BASE,
X86_ECX,
X86_EDX,
X86_EBX,
@@ -53,7 +51,7 @@ x86_get_regname(int i)
static const char *x86_regs[] = { "eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi" };
- if (i>=X86_REG_BASE && i<X86_REG_BASE + 8) return x86_regs[i - X86_REG_BASE];
+ if (i>=OJ_GP_REG_BASE && i<OJ_GP_REG_BASE + 8) return x86_regs[i - OJ_GP_REG_BASE];
switch (i) {
case 0:
return "UNALLOCATED";
@@ -67,7 +65,7 @@ x86_get_regname(int i)
static int
x86_get_regnum(int i)
{
- return i - X86_REG_BASE;
+ return i - OJ_GP_REG_BASE;
}
static const char *
@@ -76,7 +74,7 @@ x86_get_regname_16(int i)
static const char *x86_regs[] = { "ax", "cx", "dx", "bx",
"sp", "bp", "si", "di" };
- if (i>=X86_REG_BASE && i<X86_REG_BASE + 8) return x86_regs[i - X86_REG_BASE];
+ if (i>=OJ_GP_REG_BASE && i<OJ_GP_REG_BASE + 8) return x86_regs[i - OJ_GP_REG_BASE];
switch (i) {
case 0:
return "UNALLOCATED";
@@ -93,6 +91,42 @@ void oj_program_allocate_regs (OJProgram *program);
void oj_program_dump (OJProgram *program);
void
+x86_emit_prologue (OJProgram *program)
+{
+ g_print(".global test\n");
+ g_print("test:\n");
+ x86_emit_push (program, 4, X86_EBP);
+ x86_emit_mov_memoffset_reg (program, 4, 8, X86_ESP, X86_EBP);
+ x86_emit_push (program, 4, X86_EDI);
+ x86_emit_push (program, 4, X86_ESI);
+ x86_emit_push (program, 4, X86_EBX);
+}
+
+void
+x86_emit_epilogue (OJProgram *program)
+{
+ x86_emit_pop (program, 4, X86_EBX);
+ x86_emit_pop (program, 4, X86_ESI);
+ x86_emit_pop (program, 4, X86_EDI);
+ x86_emit_pop (program, 4, X86_EBP);
+ x86_emit_ret (program);
+}
+
+void
+x86_do_fixups (OJProgram *program)
+{
+ int i;
+ for(i=0;i<program->n_fixups;i++){
+ if (program->fixups[i].type == 0) {
+ unsigned char *label = program->labels[program->fixups[i].label];
+ unsigned char *ptr = program->fixups[i].ptr;
+
+ ptr[0] += label - ptr;
+ }
+ }
+}
+
+void
oj_program_compile_x86 (OJProgram *program)
{
int j;
@@ -110,27 +144,16 @@ oj_program_compile_x86 (OJProgram *program)
oj_program_rewrite_vars (program);
- printf(".global test\n");
- printf("test:\n");
- printf("# n_insns %d\n", program->n_insns);
- x86_emit_push (program, 4, X86_EBP);
- x86_emit_mov_memoffset_reg (program, 4, 8, X86_ESP, X86_EBP);
- x86_emit_push (program, 4, X86_EDI);
- x86_emit_push (program, 4, X86_ESI);
- x86_emit_push (program, 4, X86_EBX);
+ x86_emit_prologue (program);
- //g_print(" movl 0x%02x(%%ebp), %%ecx\n", (int)G_STRUCT_OFFSET(OJExecutor,n));
x86_emit_mov_memoffset_reg (program, 4, (int)G_STRUCT_OFFSET(OJExecutor,n),
X86_EBP, X86_ECX);
- //g_print(" movl %%ecx, 0x%02x(%%ebp)\n", (int)G_STRUCT_OFFSET(OJExecutor,counter));
x86_emit_mov_reg_memoffset (program, 4, X86_ECX,
(int)G_STRUCT_OFFSET(OJExecutor,counter), X86_EBP);
- //g_print(" testl %%ecx, %%ecx\n");
x86_emit_test_reg_reg (program, 4, X86_ECX, X86_ECX);
- //g_print(" je 2f\n");
x86_emit_je (program, 1);
x86_emit_label (program, 0);
@@ -148,18 +171,12 @@ oj_program_compile_x86 (OJProgram *program)
for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
switch (args[k]->vartype) {
case OJ_VAR_TYPE_SRC:
- //g_print(" movl 0x%02x(%%ebp), %%ecx\n",
- // (int)G_STRUCT_OFFSET(OJExecutor, arrays[k]));
x86_emit_mov_memoffset_reg (program, 4,
(int)G_STRUCT_OFFSET(OJExecutor, arrays[k]),
X86_EBP, X86_ECX);
- //g_print(" movw 0(%%ecx), %%%s\n",
- // x86_get_regname_16(args[k]->alloc));
x86_emit_mov_memoffset_reg (program, 2, 0, X86_ECX, args[k]->alloc);
break;
case OJ_VAR_TYPE_CONST:
- //g_print(" movl $%d, %%%s\n", args[k]->s16,
- // x86_get_regname(args[k]->alloc));
x86_emit_mov_imm_reg (program, 2, args[k]->s16, args[k]->alloc);
break;
case OJ_VAR_TYPE_TEMP:
@@ -175,11 +192,7 @@ oj_program_compile_x86 (OJProgram *program)
rule = oj_rule_list_get (list, opcode);
if (rule) {
- if (rule->flags & OJ_RULE_MUST_CHAIN_SRC1 &&
- insn->args[0] != insn->args[1]) {
- //g_print (" movw %%%s, %%%s\n",
- // x86_get_regname_16(args[1]->alloc),
- // x86_get_regname_16(args[0]->alloc));
+ if (!(rule->flags & OJ_RULE_3REG) && insn->args[0] != insn->args[1]) {
x86_emit_mov_reg_reg (program, 2, args[1]->alloc, args[0]->alloc);
}
rule->emit (program, rule->emit_user, insn);
@@ -190,13 +203,9 @@ oj_program_compile_x86 (OJProgram *program)
for(k=0;k<opcode->n_dest;k++){
switch (args[k]->vartype) {
case OJ_VAR_TYPE_DEST:
- //g_print(" movl 0x%02x(%%ebp), %%ecx\n",
- // (int)G_STRUCT_OFFSET(OJExecutor, arrays[k]));
x86_emit_mov_memoffset_reg (program, 4,
(int)G_STRUCT_OFFSET(OJExecutor, arrays[k]),
X86_EBP, X86_ECX);
- //g_print(" movw %%%s, 0(%%ecx)\n",
- // x86_get_regname_16(args[k]->alloc));
x86_emit_mov_reg_memoffset (program, 2, args[k]->alloc, 0, X86_ECX);
break;
case OJ_VAR_TYPE_TEMP:
@@ -214,158 +223,28 @@ oj_program_compile_x86 (OJProgram *program)
for(k=0;k<program->n_vars;k++){
if (program->vars[k].vartype == OJ_VAR_TYPE_SRC ||
program->vars[k].vartype == OJ_VAR_TYPE_DEST) {
- //g_print(" addl $2, 0x%02x(%%ebp)\n",
- // (int)G_STRUCT_OFFSET(OJExecutor, arrays[k]));
x86_emit_add_imm_memoffset (program, 4, 2,
(int)G_STRUCT_OFFSET(OJExecutor, arrays[k]),
X86_EBP);
}
}
- //g_print(" decl 0x%02x(%%ebp)\n", (int)G_STRUCT_OFFSET(OJExecutor,counter));
x86_emit_dec_memoffset (program, 4, (int)G_STRUCT_OFFSET(OJExecutor,counter),
X86_EBP);
- //g_print(" jne 1b\n");
x86_emit_jne (program, 0);
x86_emit_label (program, 1);
- x86_emit_pop (program, 4, X86_EBX);
- x86_emit_pop (program, 4, X86_ESI);
- x86_emit_pop (program, 4, X86_EDI);
- x86_emit_pop (program, 4, X86_EBP);
- x86_emit_ret (program);
+ x86_emit_epilogue (program);
x86_test (program);
- {
- int i;
- for(i=0;i<program->n_fixups;i++){
- if (program->fixups[i].type == 0) {
- unsigned char *label = program->labels[program->fixups[i].label];
- unsigned char *ptr = program->fixups[i].ptr;
-
- ptr[0] += label - ptr;
- }
- }
- }
+ x86_do_fixups (program);
oj_program_dump_code (program);
}
void
-oj_program_rewrite_vars (OJProgram *program)
-{
- int i;
- int j;
- int k;
- OJInstruction *insn;
- OJOpcode *opcode;
- int var;
- int actual_var;
- int alloc[8] = { 0, 1, 0, 0, 1, 1, 0, 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++){
- 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[actual_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;
- }
- }
-
- for(j=0;j<program->n_insns;j++){
- for(i=0;i<program->n_vars;i++){
- if (program->vars[i].first_use == j) {
- for(k=0;k<8;k++){
- if (!alloc[k]) {
- program->vars[i].alloc = k + X86_REG_BASE;
- alloc[k] = 1;
- break;
- }
- }
- if (k==8) {
- g_print("register overflow\n");
- }
- }
- }
- for(i=0;i<program->n_vars;i++){
- if (program->vars[i].last_use == j) {
- alloc[program->vars[i].alloc - X86_REG_BASE] = 0;
- }
- }
- }
-
-#if 0
- for(i=0;i<program->n_vars;i++){
- g_print("%2d: %2d %2d %s\n",
- i,
- program->vars[i].first_use,
- program->vars[i].last_use,
- x86_get_regname(program->vars[i].alloc));
- }
-#endif
-
-}
-
-void
oj_program_dump (OJProgram *program)
{
int i;
@@ -477,15 +356,15 @@ void
oj_program_x86_register_rules (OJRuleList *list)
{
oj_rule_list_register (list, "add_s16", x86_rule_add_s16, NULL,
- OJ_RULE_MUST_CHAIN_SRC1 | OJ_RULE_SYMMETRIC_SRC);
+ OJ_RULE_REG_REG);
oj_rule_list_register (list, "sub_s16", x86_rule_sub_s16, NULL,
- OJ_RULE_MUST_CHAIN_SRC1);
+ OJ_RULE_REG_REG);
oj_rule_list_register (list, "mul_s16", x86_rule_mul_s16, NULL,
- OJ_RULE_MUST_CHAIN_SRC1 | OJ_RULE_SYMMETRIC_SRC);
+ OJ_RULE_REG_REG);
oj_rule_list_register (list, "lshift_s16", x86_rule_lshift_s16, NULL,
- OJ_RULE_MUST_CHAIN_SRC1);
+ OJ_RULE_REG_REG);
oj_rule_list_register (list, "rshift_s16", x86_rule_rshift_s16, NULL,
- OJ_RULE_MUST_CHAIN_SRC1);
+ OJ_RULE_REG_REG);
}
@@ -500,6 +379,7 @@ oj_program_allocate_codemem (OJProgram *program)
if (fd == -1) {
/* FIXME oh crap */
g_print("failed to create temp file\n");
+ program->error = TRUE;
return;
}
unlink (filename);
@@ -511,12 +391,14 @@ oj_program_allocate_codemem (OJProgram *program)
if (program->code == MAP_FAILED) {
/* FIXME oh crap */
g_print("failed to create write map\n");
+ program->error = TRUE;
return;
}
program->code_exec = mmap (NULL, SIZE, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
if (program->code_exec == MAP_FAILED) {
/* FIXME oh crap */
g_print("failed to create exec map\n");
+ program->error = TRUE;
return;
}
@@ -531,21 +413,12 @@ oj_program_allocate_codemem (OJProgram *program)
void
oj_program_dump_code (OJProgram *program)
{
- //unsigned char *ptr;
FILE *file;
file = fopen("dump","w");
fwrite (program->code, 1, program->codeptr - program->code, file);
fclose (file);
-
-#if 0
- ptr = program->code;
- while(ptr < program->codeptr) {
- g_print("# %02x\n", ptr[0]);
- ptr++;
- }
-#endif
}
void
@@ -802,7 +675,7 @@ x86_test (OJProgram *program)
for(size=2;size<=4;size+=2) {
for(i=0;i<8;i++){
- reg = X86_REG_BASE + i;
+ reg = OJ_GP_REG_BASE + i;
x86_emit_push (program, size, reg);
x86_emit_pop (program, size, reg);
x86_emit_mov_imm_reg (program, size, 0, reg);
@@ -818,7 +691,7 @@ x86_test (OJProgram *program)
x86_emit_add_imm_memoffset (program, size, 256, 1, reg);
x86_emit_add_imm_memoffset (program, size, 256, 256, reg);
for(j=0;j<8;j++){
- int reg2 = X86_REG_BASE + j;
+ int reg2 = OJ_GP_REG_BASE + j;
x86_emit_mov_reg_reg (program, size, reg, reg2);
x86_emit_mov_memoffset_reg (program, size, 0, reg, reg2);
x86_emit_mov_memoffset_reg (program, size, 1, reg, reg2);
diff --git a/examples/jit/ojprogram.c b/examples/jit/ojprogram.c
index 340dff6..a6b0ff4 100644
--- a/examples/jit/ojprogram.c
+++ b/examples/jit/ojprogram.c
@@ -289,3 +289,115 @@ oj_rule_list_get (OJRuleList *rule_list, OJOpcode *opcode)
return NULL;
}
+void
+oj_program_rewrite_vars (OJProgram *program)
+{
+ int i;
+ int j;
+ int k;
+ OJInstruction *insn;
+ OJOpcode *opcode;
+ int var;
+ int actual_var;
+ int alloc[8] = { 0, 1, 0, 0, 1, 1, 0, 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++){
+ 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[actual_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;
+ }
+ }
+
+ for(j=0;j<program->n_insns;j++){
+ for(i=0;i<program->n_vars;i++){
+ if (program->vars[i].first_use == j) {
+ for(k=0;k<8;k++){
+ if (!alloc[k]) {
+ program->vars[i].alloc = k + OJ_GP_REG_BASE;
+ alloc[k] = 1;
+ break;
+ }
+ }
+ if (k==8) {
+ g_print("register overflow\n");
+ }
+ }
+ }
+ for(i=0;i<program->n_vars;i++){
+ if (program->vars[i].last_use == j) {
+ alloc[program->vars[i].alloc - OJ_GP_REG_BASE] = 0;
+ }
+ }
+ }
+
+#if 0
+ for(i=0;i<program->n_vars;i++){
+ g_print("%2d: %2d %2d %s\n",
+ i,
+ program->vars[i].first_use,
+ program->vars[i].last_use,
+ x86_get_regname(program->vars[i].alloc));
+ }
+#endif
+
+}
+
diff --git a/examples/jit/ojprogram.h b/examples/jit/ojprogram.h
index 0dbf4eb..6ee1710 100644
--- a/examples/jit/ojprogram.h
+++ b/examples/jit/ojprogram.h
@@ -115,10 +115,15 @@ struct _OJExecutor {
};
-#define OJ_RULE_MUST_CHAIN_SRC1 0x0001
-#define OJ_RULE_MAY_CHAIN_SRC1 0x0002
-#define OJ_RULE_SYMMETRIC_SRC 0x0004
-#define OJ_RULE_SRC2_IS_CL 0x0008
+enum {
+ OJ_RULE_3REG = (1<<0),
+ OJ_RULE_REG_REG = (1<<1),
+ OJ_RULE_MEM_REG = (1<<2),
+ OJ_RULE_REG_MEM = (1<<3),
+ OJ_RULE_REG_IMM = (1<<4),
+ OJ_RULE_MEM_IMM = (1<<5),
+ OJ_RULE_REG_CL = (1<<6)
+};
struct _OJRule {
OJOpcode *opcode;
@@ -135,6 +140,7 @@ struct _OJRuleList {
OJRule *rules;
};
+#define OJ_GP_REG_BASE 8
OJProgram * oj_program_new (void);
OJOpcode * oj_opcode_find_by_name (const char *name);