diff options
author | David Schleef <ds@wendolyne.(none)> | 2008-05-21 16:57:49 -0700 |
---|---|---|
committer | David Schleef <ds@wendolyne.(none)> | 2008-05-21 16:57:49 -0700 |
commit | fdf3c5067916e0a823b3e57c9338fca2f718084b (patch) | |
tree | 29ac950e98395609b8bcbc904258b5efd1e71301 | |
parent | 63b97ea1055a6e8da5cce2db5ba3e3f1e520ed49 (diff) | |
download | liboil-fdf3c5067916e0a823b3e57c9338fca2f718084b.tar.gz |
[orc] implement powerpc assembly.
-rw-r--r-- | examples/orc/jit.c | 33 | ||||
-rw-r--r-- | orc/orcexecutor.c | 5 | ||||
-rw-r--r-- | orc/orcprogram-powerpc.c | 668 |
3 files changed, 317 insertions, 389 deletions
diff --git a/examples/orc/jit.c b/examples/orc/jit.c index 868d9a4..bbc3e50 100644 --- a/examples/orc/jit.c +++ b/examples/orc/jit.c @@ -8,7 +8,7 @@ #include <orc/orcprogram.h> -#define N 10 +#define N 20 int16_t src1[N]; int16_t src2[N]; @@ -35,24 +35,19 @@ main (int argc, char *argv[]) offset = orc_program_add_constant (p, "s16", 1, "offset"); shift = orc_program_add_constant (p, "s16", 1, "shift"); +#if 0 orc_program_append (p, "add_s16", t1, s1, s2); orc_program_append (p, "add_s16", t1, t1, offset); orc_program_append (p, "rshift_s16", d1, t1, shift); +#endif -#if 0 - orc_program_append (p, "lshift_s16", t1, t1, shift); - orc_program_append (p, "sub_s16", t1, t1, shift); - orc_program_append (p, "mul_s16", t1, t1, shift); +#if 1 + orc_program_append (p, "lshift_s16", d1, s1, shift); + //orc_program_append (p, "sub_s16", t1, t1, shift); + //orc_program_append (p, "mul_s16", d1, s1, s2); //orc_program_append (p, "_loadi_s16", t1, t1, shift); #endif - ex = orc_executor_new (p); - - orc_executor_set_n (ex, N); - orc_executor_set_array (ex, s1, src1); - orc_executor_set_array (ex, s2, src2); - orc_executor_set_array (ex, d1, dest); - orc_program_compile (p); if (1) { @@ -63,16 +58,26 @@ main (int argc, char *argv[]) src2[i] = rand()&0xf; } + ex = orc_executor_new (p); + + orc_executor_set_n (ex, N); + orc_executor_set_array (ex, s1, src1); + orc_executor_set_array (ex, s2, src2); + orc_executor_set_array (ex, d1, dest); + + printf("#code exec %p\n", ex->program->code_exec); + orc_executor_run (ex); //orc_executor_emulate (ex); for(i=0;i<N;i++){ printf("# %4d %4d %4d %4d\n", src1[i], src2[i], dest[i], - (src1[i] + src2[i] + 1)>>1); + src1[i] << 1); } + + orc_executor_free (ex); } - orc_executor_free (ex); orc_program_free (p); return 0; diff --git a/orc/orcexecutor.c b/orc/orcexecutor.c index d6b9282..306c929 100644 --- a/orc/orcexecutor.c +++ b/orc/orcexecutor.c @@ -14,7 +14,8 @@ orc_executor_new (OrcProgram *program) { OrcExecutor *ex; - ex = g_malloc0(sizeof(OrcExecutor)); + ex = malloc(sizeof(OrcExecutor)); + memset(ex,0,sizeof(OrcExecutor)); ex->program = program; @@ -26,7 +27,7 @@ orc_executor_new (OrcProgram *program) void orc_executor_free (OrcExecutor *ex) { - g_free (ex); + free (ex); } void diff --git a/orc/orcprogram-powerpc.c b/orc/orcprogram-powerpc.c index 08590cc..776870a 100644 --- a/orc/orcprogram-powerpc.c +++ b/orc/orcprogram-powerpc.c @@ -14,39 +14,15 @@ #define SIZE 65536 -#if 0 -void x86_emit_push (OrcProgram *program, int size, int reg); -void x86_emit_pop (OrcProgram *program, int size, int reg); -void x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset, int reg1, int reg2); -void x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset, - int reg1, int reg2); -void x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset, int reg2); -void x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset, - int reg2); -void x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1); -void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2); -void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2); -void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2); -void x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2); -void x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg); -void x86_emit_dec_memoffset (OrcProgram *program, int size, int offset, int reg); -void x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg); -void x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg); -void x86_emit_emms (OrcProgram *program); -#endif +void powerpc_emit_addi (OrcProgram *program, int regd, int rega, int imm); +void powerpc_emit_lwz (OrcProgram *program, int regd, int rega, int imm); +void powerpc_emit_stwu (OrcProgram *program, int regs, int rega, int offset); + void powerpc_emit_ret (OrcProgram *program); void powerpc_emit_beq (OrcProgram *program, int label); void powerpc_emit_bne (OrcProgram *program, int label); void powerpc_emit_label (OrcProgram *program, int label); -#if 0 -static void mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value); - -void x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2); -void x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2); -void x86_test (OrcProgram *program); -#endif - void orc_program_powerpc_register_rules (void); enum { @@ -81,7 +57,39 @@ enum { POWERPC_R28, POWERPC_R29, POWERPC_R30, - POWERPC_R31 + POWERPC_R31, + POWERPC_V0, + POWERPC_V1, + POWERPC_V2, + POWERPC_V3, + POWERPC_V4, + POWERPC_V5, + POWERPC_V6, + POWERPC_V7, + POWERPC_V8, + POWERPC_V9, + POWERPC_V10, + POWERPC_V11, + POWERPC_V12, + POWERPC_V13, + POWERPC_V14, + POWERPC_V15, + POWERPC_V16, + POWERPC_V17, + POWERPC_V18, + POWERPC_V19, + POWERPC_V20, + POWERPC_V21, + POWERPC_V22, + POWERPC_V23, + POWERPC_V24, + POWERPC_V25, + POWERPC_V26, + POWERPC_V27, + POWERPC_V28, + POWERPC_V29, + POWERPC_V30, + POWERPC_V31 }; const char * @@ -112,6 +120,12 @@ powerpc_get_regname(int i) } int +powerpc_regnum (int i) +{ + return (i-ORC_GP_REG_BASE)&0x1f; +} + +int orc_program_powerpc_allocate_register (OrcProgram *program, int data_reg) { int i; @@ -142,6 +156,15 @@ void orc_program_rewrite_vars (OrcProgram *program); void orc_program_dump (OrcProgram *program); void +powerpc_emit(OrcProgram *program, unsigned int insn) +{ + *program->codeptr++ = (insn>>24); + *program->codeptr++ = (insn>>16); + *program->codeptr++ = (insn>>8); + *program->codeptr++ = (insn>>0); +} + +void powerpc_emit_prologue (OrcProgram *program) { int i; @@ -149,9 +172,7 @@ powerpc_emit_prologue (OrcProgram *program) printf (".global test\n"); printf ("test:\n"); - printf (" stwu %s,-16(%s)\n", - powerpc_get_regname(POWERPC_R1), - powerpc_get_regname(POWERPC_R1)); + powerpc_emit_stwu (program, POWERPC_R1, POWERPC_R1, -16); for(i=POWERPC_R13;i<=POWERPC_R31;i++){ if (program->used_regs[i]) { @@ -161,6 +182,113 @@ powerpc_emit_prologue (OrcProgram *program) } void +powerpc_emit_addi (OrcProgram *program, int regd, int rega, int imm) +{ + unsigned int insn; + + printf(" addi %s, %s, %d\n", + powerpc_get_regname(regd), + powerpc_get_regname(rega), imm); + insn = (14<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= imm&0xffff; + + powerpc_emit (program, insn); +} + +void +powerpc_emit_lwz (OrcProgram *program, int regd, int rega, int imm) +{ + unsigned int insn; + + printf(" lwz %s, %d(%s)\n", + powerpc_get_regname(regd), + imm, powerpc_get_regname(rega)); + insn = (32<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= imm&0xffff; + + powerpc_emit (program, insn); +} + +void +powerpc_emit_stwu (OrcProgram *program, int regs, int rega, int offset) +{ + unsigned int insn; + + printf(" stwu %s, %d(%s)\n", + powerpc_get_regname(regs), + offset, powerpc_get_regname(rega)); + insn = (37<<26) | (powerpc_regnum (regs)<<21) | (powerpc_regnum (rega)<<16); + insn |= offset&0xffff; + + powerpc_emit (program, insn); +} + +void +powerpc_emit_srawi (OrcProgram *program, int regd, int rega, int shift, + int record) +{ + unsigned int insn; + + printf(" srawi%s %s, %s, %d\n", (record)?".":"", + powerpc_get_regname(regd), + powerpc_get_regname(rega), shift); + + insn = (31<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= (shift<<11) | (824<<1) | record; + + powerpc_emit (program, insn); +} + +void +powerpc_emit_655510 (OrcProgram *program, int major, int d, int a, int b, + int minor) +{ + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (minor<<0); + + powerpc_emit (program, insn); +} + +void +powerpc_emit_X (OrcProgram *program, int major, int d, int a, int b, + int minor) +{ + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (minor<<1) | (0<<0); + + powerpc_emit (program, insn); +} + +void +powerpc_emit_VA (OrcProgram *program, int major, int d, int a, int b, + int c, int minor) +{ + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (c<<6) | (minor<<0); + + powerpc_emit (program, insn); +} + +void +powerpc_emit_VX (OrcProgram *program, int major, int d, int a, int b, + int minor) +{ + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (minor<<0); + + powerpc_emit (program, insn); +} + + +void powerpc_emit_epilogue (OrcProgram *program) { int i; @@ -171,26 +299,48 @@ powerpc_emit_epilogue (OrcProgram *program) } } - printf(" addi %s, %s, 16\n", - powerpc_get_regname(POWERPC_R1), - powerpc_get_regname(POWERPC_R1)); + powerpc_emit_addi (program, POWERPC_R1, POWERPC_R1, 16); printf(" blr\n"); + powerpc_emit(program, 0x4e800020); } void powerpc_do_fixups (OrcProgram *program) { -#if 0 int i; + unsigned int insn; + 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; + insn = *(unsigned int *)ptr; + *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-ptr))&0xffff); } } -#endif +} + +void +powerpc_flush (OrcProgram *program) +{ + unsigned char *ptr; + int cache_line_size = 32; + int i; + int size = program->codeptr - program->code; + + ptr = program->code; + for (i=0;i<size;i+=cache_line_size) { + __asm__ __volatile__ ("dcbst %0,%1" :: "r" (ptr), "r" (i)); + } + __asm__ __volatile ("sync"); + + ptr = program->code_exec; + for (i=0;i<size;i+=cache_line_size) { + __asm__ __volatile__ ("icbi %0,%1" :: "r" (ptr), "r" (i)); + } + __asm__ __volatile ("isync"); + } void @@ -207,9 +357,10 @@ orc_program_powerpc_reset_alloc (OrcProgram *program) for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+64;i++){ program->alloc_regs[i] = 0; } - program->alloc_regs[POWERPC_R0] = 1; - program->alloc_regs[POWERPC_R1] = 1; - program->alloc_regs[POWERPC_R3] = 1; + for(i=0;i<9;i++){ + program->alloc_regs[POWERPC_R0 + i] = 1; + } + program->alloc_regs[POWERPC_V0] = 1; } void @@ -222,14 +373,17 @@ powerpc_load_constants (OrcProgram *program) printf(" vspltish %s, %d\n", powerpc_get_regname(program->vars[i].alloc), program->vars[i].s16); + powerpc_emit_655510 (program, 4, + powerpc_regnum(program->vars[i].alloc), + program->vars[i].s16, 0, 844); break; case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: if (program->vars[i].ptr_register) { - printf(" ldw %s, %d(%s)\n", - powerpc_get_regname(program->vars[i].ptr_register), - (int)G_STRUCT_OFFSET(OrcExecutor, arrays[i]), - powerpc_get_regname(POWERPC_R3)); + powerpc_emit_lwz (program, + program->vars[i].ptr_register, + POWERPC_R3, + (int)G_STRUCT_OFFSET(OrcExecutor, arrays[i])); } else { /* FIXME */ printf("ERROR"); @@ -249,9 +403,26 @@ powerpc_emit_load_src (OrcProgram *program, OrcVariable *var) switch (program->rule_set) { case ORC_RULE_ALTIVEC_1: - printf(" lvehx %s, 0(%s)\n", + printf(" lvehx %s, 0, %s\n", powerpc_get_regname (var->alloc), powerpc_get_regname (ptr_reg)); + powerpc_emit_X (program, 31, powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg), 39); + printf(" lvsl %s, 0, %s\n", + powerpc_get_regname (POWERPC_V0), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (program, 31, powerpc_regnum(POWERPC_V0), + 0, powerpc_regnum(ptr_reg), 6); + printf(" vperm %s, %s, %s, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (POWERPC_V0)); + powerpc_emit_VA (program, 4, + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(POWERPC_V0), 43); break; default: printf("ERROR\n"); @@ -266,9 +437,27 @@ powerpc_emit_store_dest (OrcProgram *program, OrcVariable *var) switch (program->rule_set) { case ORC_RULE_ALTIVEC_1: - printf(" stvehx %s, 0(%s)\n", + printf(" lvsr %s, 0, %s\n", + powerpc_get_regname (POWERPC_V0), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (program, 31, powerpc_regnum(POWERPC_V0), + 0, powerpc_regnum(ptr_reg), 38); + printf(" vperm %s, %s, %s, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (POWERPC_V0)); + powerpc_emit_VA (program, 4, + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(POWERPC_V0), 43); + printf(" stvehx %s, 0, %s\n", powerpc_get_regname (var->alloc), powerpc_get_regname (ptr_reg)); + powerpc_emit_X (program, 31, + powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg), 167); break; default: printf("ERROR\n"); @@ -287,18 +476,14 @@ orc_program_assemble_powerpc (OrcProgram *program) powerpc_emit_prologue (program); - printf(" ldw. %s, %d(%s)\n", - powerpc_get_regname(POWERPC_R0), - (int)G_STRUCT_OFFSET(OrcExecutor, n), - powerpc_get_regname(POWERPC_R3)); - if (program->loop_shift != 0) { - printf(" srawi. %s, %s, %d\n", - powerpc_get_regname(POWERPC_R0), - powerpc_get_regname(POWERPC_R0), - program->loop_shift); - } + powerpc_emit_lwz (program, POWERPC_R0, POWERPC_R3, + (int)G_STRUCT_OFFSET(OrcExecutor, n)); + powerpc_emit_srawi (program, POWERPC_R0, POWERPC_R0, + program->loop_shift, 1); powerpc_emit_beq (program, 1); + + powerpc_emit (program, 0x7c0903a6); printf (" mtctr %s\n", powerpc_get_regname(POWERPC_R0)); powerpc_load_constants (program); @@ -360,9 +545,9 @@ orc_program_assemble_powerpc (OrcProgram *program) if (program->vars[k].vartype == ORC_VAR_TYPE_SRC || program->vars[k].vartype == ORC_VAR_TYPE_DEST) { if (program->vars[k].ptr_register) { - printf(" addi %s, %s, %d\n", - powerpc_get_regname(program->vars[k].ptr_register), - powerpc_get_regname(program->vars[k].ptr_register), + powerpc_emit_addi (program, + program->vars[k].ptr_register, + program->vars[k].ptr_register, orc_variable_get_size(program->vars + k) << program->loop_shift); } else { printf("ERROR\n"); @@ -376,6 +561,8 @@ orc_program_assemble_powerpc (OrcProgram *program) powerpc_emit_epilogue (program); powerpc_do_fixups (program); + + powerpc_flush (program); } @@ -384,10 +571,20 @@ orc_program_assemble_powerpc (OrcProgram *program) static void powerpc_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn) { + unsigned int x; + printf(" vadduhm %s, %s, %s\n", powerpc_get_regname(p->vars[insn->args[0]].alloc), powerpc_get_regname(p->vars[insn->args[1]].alloc), powerpc_get_regname(p->vars[insn->args[2]].alloc)); + + x = (4<<26); + x |= (powerpc_regnum (p->vars[insn->args[0]].alloc)<<21); + x |= (powerpc_regnum (p->vars[insn->args[1]].alloc)<<16); + x |= (powerpc_regnum (p->vars[insn->args[2]].alloc)<<11); + x |= 64; + + powerpc_emit (p, x); } static void @@ -402,10 +599,26 @@ powerpc_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn) static void powerpc_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn) { - printf(" vmladduhm %s, %s, %s, vzero\n", + printf(" vxor %s, %s, %s\n", + powerpc_get_regname(POWERPC_V0), + powerpc_get_regname(POWERPC_V0), + powerpc_get_regname(POWERPC_V0)); + powerpc_emit_VX(p, 4, + powerpc_regnum(POWERPC_V0), + powerpc_regnum(POWERPC_V0), + powerpc_regnum(POWERPC_V0), 1220); + + printf(" vmladduhm %s, %s, %s, %s\n", powerpc_get_regname(p->vars[insn->args[0]].alloc), powerpc_get_regname(p->vars[insn->args[1]].alloc), - powerpc_get_regname(p->vars[insn->args[2]].alloc)); + powerpc_get_regname(p->vars[insn->args[2]].alloc), + powerpc_get_regname(POWERPC_V0)); + powerpc_emit_VA(p, 4, + powerpc_regnum(p->vars[insn->args[0]].alloc), + powerpc_regnum(p->vars[insn->args[1]].alloc), + powerpc_regnum(p->vars[insn->args[2]].alloc), + powerpc_regnum(POWERPC_V0), 34); + } static void @@ -415,15 +628,29 @@ powerpc_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn) powerpc_get_regname(p->vars[insn->args[0]].alloc), powerpc_get_regname(p->vars[insn->args[1]].alloc), powerpc_get_regname(p->vars[insn->args[2]].alloc)); + powerpc_emit_VX(p, 4, + powerpc_regnum(p->vars[insn->args[0]].alloc), + powerpc_regnum(p->vars[insn->args[1]].alloc), + powerpc_regnum(p->vars[insn->args[2]].alloc), 68); } static void powerpc_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn) { + unsigned int x; + printf(" vsrah %s, %s, %s\n", powerpc_get_regname(p->vars[insn->args[0]].alloc), powerpc_get_regname(p->vars[insn->args[1]].alloc), powerpc_get_regname(p->vars[insn->args[2]].alloc)); + + x = (4<<26); + x |= (powerpc_regnum (p->vars[insn->args[0]].alloc)<<21); + x |= (powerpc_regnum (p->vars[insn->args[1]].alloc)<<16); + x |= (powerpc_regnum (p->vars[insn->args[2]].alloc)<<11); + x |= 836; + + powerpc_emit (p, x); } @@ -444,320 +671,20 @@ orc_program_powerpc_register_rules (void) /* code generation */ -#if 0 -void -x86_emit_push (OrcProgram *program, int size, int reg) -{ - - if (size == 1) { - program->error = 1; - } else if (size == 2) { - g_print(" pushw %%%s\n", x86_get_regname_16(reg)); - *program->codeptr++ = 0x66; - *program->codeptr++ = 0x50 + x86_get_regnum(reg); - } else { - g_print(" pushl %%%s\n", x86_get_regname(reg)); - *program->codeptr++ = 0x50 + x86_get_regnum(reg); - } -} - -void -x86_emit_pop (OrcProgram *program, int size, int reg) -{ - - if (size == 1) { - program->error = 1; - } else if (size == 2) { - g_print(" popw %%%s\n", x86_get_regname_16(reg)); - *program->codeptr++ = 0x66; - *program->codeptr++ = 0x58 + x86_get_regnum(reg); - } else { - g_print(" popl %%%s\n", x86_get_regname(reg)); - *program->codeptr++ = 0x58 + x86_get_regnum(reg); - } -} - -#define X86_MODRM(mod, rm, reg) ((((mod)&3)<<6)|(((rm)&7)<<0)|(((reg)&7)<<3)) -#define X86_SIB(ss, ind, reg) ((((ss)&3)<<6)|(((ind)&7)<<3)|((reg)&7)) - -void -x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2) -{ - if (offset == 0 && reg2 != X86_EBP) { - if (reg2 == X86_ESP) { - *program->codeptr++ = X86_MODRM(0, 4, reg1); - *program->codeptr++ = X86_SIB(0, 4, reg2); - } else { - *program->codeptr++ = X86_MODRM(0, reg2, reg1); - } - } else if (offset >= -128 && offset < 128) { - *program->codeptr++ = X86_MODRM(1, reg2, reg1); - if (reg2 == X86_ESP) { - *program->codeptr++ = X86_SIB(0, 4, reg2); - } - *program->codeptr++ = (offset & 0xff); - } else { - *program->codeptr++ = X86_MODRM(2, reg2, reg1); - if (reg2 == X86_ESP) { - *program->codeptr++ = X86_SIB(0, 4, reg2); - } - *program->codeptr++ = (offset & 0xff); - *program->codeptr++ = ((offset>>8) & 0xff); - *program->codeptr++ = ((offset>>16) & 0xff); - *program->codeptr++ = ((offset>>24) & 0xff); - } -} - -void -x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2) -{ - *program->codeptr++ = X86_MODRM(3, reg1, reg2); -} - -void -x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset, - int reg1, int reg2) -{ - if (size == 2) { - g_print(" movw %d(%%%s), %%%s\n", offset, x86_get_regname(reg1), - x86_get_regname_16(reg2)); - *program->codeptr++ = 0x66; - } else { - g_print(" movl %d(%%%s), %%%s\n", offset, x86_get_regname(reg1), - x86_get_regname(reg2)); - } - - *program->codeptr++ = 0x8b; - x86_emit_modrm_memoffset (program, reg2, offset, reg1); -} - -void -x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset, - int reg1, int reg2) -{ - if (size == 4) { - g_print(" movd %d(%%%s), %%%s\n", offset, x86_get_regname(reg1), - x86_get_regname_mmx(reg2)); - *program->codeptr++ = 0x0f; - *program->codeptr++ = 0x6e; - } else { - g_print(" movq %d(%%%s), %%%s\n", offset, x86_get_regname(reg1), - x86_get_regname_mmx(reg2)); - *program->codeptr++ = 0x0f; - *program->codeptr++ = 0x6f; - } - x86_emit_modrm_memoffset (program, reg2, offset, reg1); -} - -void -x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset, - int reg2) -{ - if (size == 2) { - g_print(" movw %%%s, %d(%%%s)\n", x86_get_regname_16(reg1), offset, - x86_get_regname(reg2)); - *program->codeptr++ = 0x66; - } else { - g_print(" movl %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset, - x86_get_regname(reg2)); - } - - *program->codeptr++ = 0x89; - x86_emit_modrm_memoffset (program, reg1, offset, reg2); -} - -void -x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset, - int reg2) -{ - if (size == 4) { - g_print(" movd %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset, - x86_get_regname(reg2)); - *program->codeptr++ = 0x0f; - *program->codeptr++ = 0x7e; - } else { - g_print(" movq %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset, - x86_get_regname(reg2)); - *program->codeptr++ = 0x0f; - *program->codeptr++ = 0x7f; - } - - x86_emit_modrm_memoffset (program, reg1, offset, reg2); -} - -void -x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1) -{ - if (size == 2) { - g_print(" movw $%d, %%%s\n", value, x86_get_regname_16(reg1)); - *program->codeptr++ = 0x66; - *program->codeptr++ = 0xb8 + x86_get_regnum(reg1); - *program->codeptr++ = (value & 0xff); - *program->codeptr++ = ((value>>8) & 0xff); - } else { - g_print(" movl $%d, %%%s\n", value, x86_get_regname(reg1)); - *program->codeptr++ = 0xb8 + x86_get_regnum(reg1); - *program->codeptr++ = (value & 0xff); - *program->codeptr++ = ((value>>8) & 0xff); - *program->codeptr++ = ((value>>16) & 0xff); - *program->codeptr++ = ((value>>24) & 0xff); - } - -} - -void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2) -{ - if (size == 2) { - g_print(" movw %%%s, %%%s\n", x86_get_regname_16(reg1), - x86_get_regname_16(reg2)); - *program->codeptr++ = 0x66; - } else { - g_print(" movl %%%s, %%%s\n", x86_get_regname(reg1), - x86_get_regname(reg2)); - } - - *program->codeptr++ = 0x89; - x86_emit_modrm_reg (program, reg2, reg1); -} - -void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2) -{ - /* FIXME */ - g_print(" movd %%%s, %%%s\n", x86_get_regname(reg1), - x86_get_regname_mmx(reg2)); - *program->codeptr++ = 0x0f; - *program->codeptr++ = 0x6e; - x86_emit_modrm_reg (program, reg1, reg2); -} - -void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2) -{ - /* FIXME */ - g_print(" movd %%%s, %%%s\n", x86_get_regname_mmx(reg1), - x86_get_regname(reg2)); - *program->codeptr++ = 0x0f; - *program->codeptr++ = 0x7e; - x86_emit_modrm_reg (program, reg2, reg1); -} - -void -x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2) -{ - if (size == 2) { - g_print(" testw %%%s, %%%s\n", x86_get_regname_16(reg1), - x86_get_regname_16(reg2)); - *program->codeptr++ = 0x66; - } else { - g_print(" testl %%%s, %%%s\n", x86_get_regname(reg1), - x86_get_regname(reg2)); - } - - *program->codeptr++ = 0x85; - x86_emit_modrm_reg (program, reg2, reg1); -} - -void -x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg) -{ - g_print(" sarl $%d, %%%s\n", value, x86_get_regname(reg)); - - if (value == 1) { - *program->codeptr++ = 0xd1; - x86_emit_modrm_reg (program, reg, 7); - } else { - *program->codeptr++ = 0xc1; - x86_emit_modrm_reg (program, reg, 7); - *program->codeptr++ = value; - } -} - -void -x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value, - int offset, int reg) -{ - if (size == 2) { - g_print(" addw $%d, %d(%%%s)\n", value, offset, - x86_get_regname(reg)); - *program->codeptr++ = 0x66; - } else { - g_print(" addl $%d, %d(%%%s)\n", value, offset, - x86_get_regname(reg)); - } - - if (value >= -128 && value < 128) { - *program->codeptr++ = 0x83; - x86_emit_modrm_memoffset (program, 0, offset, reg); - *program->codeptr++ = (value & 0xff); - } else { - *program->codeptr++ = 0x81; - x86_emit_modrm_memoffset (program, 0, offset, reg); - *program->codeptr++ = (value & 0xff); - *program->codeptr++ = ((value>>8) & 0xff); - if (size == 4) { - *program->codeptr++ = ((value>>16) & 0xff); - *program->codeptr++ = ((value>>24) & 0xff); - } - } -} - -void -x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg) -{ - if (size == 2) { - g_print(" addw $%d, %%%s\n", value, x86_get_regname_16(reg)); - *program->codeptr++ = 0x66; - } else { - g_print(" addl $%d, %%%s\n", value, x86_get_regname(reg)); - } - - if (value >= -128 && value < 128) { - *program->codeptr++ = 0x83; - x86_emit_modrm_reg (program, reg, 0); - *program->codeptr++ = (value & 0xff); - } else { - *program->codeptr++ = 0x81; - x86_emit_modrm_reg (program, reg, 0); - *program->codeptr++ = (value & 0xff); - *program->codeptr++ = ((value>>8) & 0xff); - if (size == 4) { - *program->codeptr++ = ((value>>16) & 0xff); - *program->codeptr++ = ((value>>24) & 0xff); - } - } -} - -void -x86_emit_dec_memoffset (OrcProgram *program, int size, - int offset, int reg) -{ - if (size == 2) { - g_print(" decw %d(%%%s)\n", offset, x86_get_regname(reg)); - *program->codeptr++ = 0x66; - } else { - g_print(" decl %d(%%%s)\n", offset, x86_get_regname(reg)); - } - - *program->codeptr++ = 0xff; - x86_emit_modrm_memoffset (program, 1, offset, reg); -} -#endif - void powerpc_emit_ret (OrcProgram *program) { g_print(" ret\n"); //*program->codeptr++ = 0xc3; } -#if 0 void -x86_add_fixup (OrcProgram *program, unsigned char *ptr, int label) +powerpc_add_fixup (OrcProgram *program, unsigned char *ptr, int label) { program->fixups[program->n_fixups].ptr = ptr; program->fixups[program->n_fixups].label = label; program->fixups[program->n_fixups].type = 0; program->n_fixups++; } -#endif void powerpc_add_label (OrcProgram *program, unsigned char *ptr, int label) @@ -769,21 +696,16 @@ void powerpc_emit_beq (OrcProgram *program, int label) { g_print(" ble- .L%d\n", label); -#if 0 - *program->codeptr++ = 0x74; - x86_add_fixup (program, program->codeptr, label); - *program->codeptr++ = -1; -#endif + powerpc_add_fixup (program, program->codeptr, label); + powerpc_emit (program, 0x40810000); } void powerpc_emit_bne (OrcProgram *program, int label) { g_print(" bdnz+ .L%d\n", label); -#if 0 - *program->codeptr++ = 0x75; - x86_add_fixup (program, program->codeptr, label); - *program->codeptr++ = -1; -#endif + + powerpc_add_fixup (program, program->codeptr, label); + powerpc_emit (program, 0x42000000); } void powerpc_emit_label (OrcProgram *program, int label) |