summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@wendolyne.(none)>2008-05-21 16:57:49 -0700
committerDavid Schleef <ds@wendolyne.(none)>2008-05-21 16:57:49 -0700
commitfdf3c5067916e0a823b3e57c9338fca2f718084b (patch)
tree29ac950e98395609b8bcbc904258b5efd1e71301
parent63b97ea1055a6e8da5cce2db5ba3e3f1e520ed49 (diff)
downloadliboil-fdf3c5067916e0a823b3e57c9338fca2f718084b.tar.gz
[orc] implement powerpc assembly.
-rw-r--r--examples/orc/jit.c33
-rw-r--r--orc/orcexecutor.c5
-rw-r--r--orc/orcprogram-powerpc.c668
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)