diff options
author | David Schleef <ds@ginger.bigkitten.com> | 2008-05-15 00:30:59 -0700 |
---|---|---|
committer | David Schleef <ds@ginger.bigkitten.com> | 2008-05-15 00:30:59 -0700 |
commit | 1501bac739641b8a5bf91a16dae3a849f7544d33 (patch) | |
tree | 3c068889041ae2d581020fbe4ad9ab867efaf492 /examples | |
parent | 6d4c856e5b2ea343f90173a77b5de5153ce4fdcc (diff) |
jit: code cleanup
Diffstat (limited to 'examples')
-rw-r--r-- | examples/jit/ojprogram-x86.c | 235 | ||||
-rw-r--r-- | examples/jit/ojprogram.c | 112 | ||||
-rw-r--r-- | examples/jit/ojprogram.h | 14 |
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); |