summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pavone <pavone@retrodev.com>2013-01-04 23:21:07 -0800
committerMike Pavone <pavone@retrodev.com>2013-01-04 23:21:07 -0800
commitb6daf2b7bc951d54ffe49e83cc96b30d7f34bc23 (patch)
treef841800f5647d65322c01a241e5615408a656663
parentdc1db1cf80f9a8b4067f9122527884e2f47e3a6e (diff)
Don't use the native call stack for M68K calls by default
-rw-r--r--m68k_to_x86.c119
-rw-r--r--m68k_to_x86.h2
2 files changed, 88 insertions, 33 deletions
diff --git a/m68k_to_x86.c b/m68k_to_x86.c
index 8c50b10..70c471a 100644
--- a/m68k_to_x86.c
+++ b/m68k_to_x86.c
@@ -1398,7 +1398,9 @@ uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
//TODO: Add cycles in the right place relative to pushing the return address on the stack
dst = cycles(dst, 10);
dst = mov_ir(dst, after, SCRATCH1, SZ_D);
- dst = push_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = push_r(dst, SCRATCH1);
+ }
dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
dst = call(dst, (char *)m68k_write_long_highfirst);
@@ -1406,11 +1408,15 @@ uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
if (!dest_addr) {
opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1);
//dummy address to be replaced later
- dest_addr = dst + 5;
+ dest_addr = dst + 256;
+ }
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call(dst, (char *)dest_addr);
+ //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
+ dst = pop_r(dst, SCRATCH1);
+ } else {
+ dst = jmp(dst, (char *)dest_addr);
}
- dst = call(dst, (char *)dest_addr);
- //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
- dst = pop_r(dst, SCRATCH1);
return dst;
}
@@ -1725,7 +1731,9 @@ uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
case MODE_AREG_INDIRECT:
dst = cycles(dst, BUS*2);
dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D);
- dst = push_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = push_r(dst, SCRATCH1);
+ }
dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
dst = call(dst, (char *)m68k_write_long_highfirst);
@@ -1735,14 +1743,20 @@ uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
}
dst = call(dst, (uint8_t *)m68k_native_addr);
- dst = call_r(dst, SCRATCH1);
- //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
- dst = pop_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call_r(dst, SCRATCH1);
+ //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
+ dst = pop_r(dst, SCRATCH1);
+ } else {
+ dst = jmp_r(dst, SCRATCH1);
+ }
break;
case MODE_AREG_INDEX_DISP8:
dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
- dst = push_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = push_r(dst, SCRATCH1);
+ }
dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
dst = call(dst, (char *)m68k_write_long_highfirst);
@@ -1786,15 +1800,21 @@ uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
}
dst = call(dst, (uint8_t *)m68k_native_addr);
- dst = call_r(dst, SCRATCH1);
- //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
- dst = pop_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call_r(dst, SCRATCH1);
+ //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
+ dst = pop_r(dst, SCRATCH1);
+ } else {
+ dst = jmp_r(dst, SCRATCH1);
+ }
break;
case MODE_PC_DISPLACE:
//TODO: Add cycles in the right place relative to pushing the return address on the stack
dst = cycles(dst, 10);
dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
- dst = push_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = push_r(dst, SCRATCH1);
+ }
dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
dst = call(dst, (char *)m68k_write_long_highfirst);
@@ -1804,21 +1824,33 @@ uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
if (!dest_addr) {
opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
//dummy address to be replaced later, make sure it generates a 4-byte displacement
- dest_addr = dst + 5;
+ dest_addr = dst + 256;
+ }
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call(dst, (char *)dest_addr);
+ } else {
+ dst = jmp(dst, dest_addr);
}
- dst = call(dst, (char *)dest_addr);
} else {
dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
dst = call(dst, (uint8_t *)m68k_native_addr);
- dst = call_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call_r(dst, SCRATCH1);
+ } else {
+ dst = jmp_r(dst, SCRATCH1);
+ }
+ }
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
+ dst = pop_r(dst, SCRATCH1);
}
- //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
- dst = pop_r(dst, SCRATCH1);
break;
case MODE_PC_INDEX_DISP8:
dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
- dst = push_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = push_r(dst, SCRATCH1);
+ }
dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
dst = call(dst, (char *)m68k_write_long_highfirst);
@@ -1858,16 +1890,22 @@ uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
}
dst = call(dst, (uint8_t *)m68k_native_addr);
- dst = call_r(dst, SCRATCH1);
- //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
- dst = pop_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call_r(dst, SCRATCH1);
+ //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
+ dst = pop_r(dst, SCRATCH1);
+ } else {
+ dst = jmp_r(dst, SCRATCH1);
+ }
break;
case MODE_ABSOLUTE:
case MODE_ABSOLUTE_SHORT:
//TODO: Add cycles in the right place relative to pushing the return address on the stack
dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D);
- dst = push_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = push_r(dst, SCRATCH1);
+ }
dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
dst = call(dst, (char *)m68k_write_long_highfirst);
@@ -1877,16 +1915,26 @@ uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * o
if (!dest_addr) {
opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
//dummy address to be replaced later, make sure it generates a 4-byte displacement
- dest_addr = dst + 5;
+ dest_addr = dst + 256;
+ }
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call(dst, (char *)dest_addr);
+ } else {
+ dst = jmp(dst, dest_addr);
}
- dst = call(dst, (char *)dest_addr);
} else {
dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
dst = call(dst, (uint8_t *)m68k_native_addr);
- dst = call_r(dst, SCRATCH1);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = call_r(dst, SCRATCH1);
+ } else {
+ dst = jmp_r(dst, SCRATCH1);
+ }
+ }
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
+ dst = pop_r(dst, SCRATCH1);
}
- //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
- dst = pop_r(dst, SCRATCH1);
break;
default:
m68k_disasm(inst, disasm_buf);
@@ -1902,10 +1950,15 @@ uint8_t * translate_m68k_rts(uint8_t * dst, m68kinst * inst, x86_68k_options * o
dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
dst = call(dst, (char *)m68k_read_long_scratch1);
- dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D);
- dst = jcc(dst, CC_NZ, dst+3);
- dst = retn(dst);
- dst = jmp(dst, (char *)m68k_modified_ret_addr);
+ if (opts->flags & OPT_NATIVE_CALL_STACK) {
+ dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D);
+ dst = jcc(dst, CC_NZ, dst+3);
+ dst = retn(dst);
+ dst = jmp(dst, (char *)m68k_modified_ret_addr);
+ } else {
+ dst = call(dst, (uint8_t *)m68k_native_addr);
+ dst = jmp_r(dst, SCRATCH1);
+ }
return dst;
}
diff --git a/m68k_to_x86.h b/m68k_to_x86.h
index 7871c6a..24e6774 100644
--- a/m68k_to_x86.h
+++ b/m68k_to_x86.h
@@ -6,6 +6,8 @@
#define NATIVE_CHUNK_SIZE ((16 * 1024 * 1024 / NATIVE_MAP_CHUNKS)/2)
#define INVALID_OFFSET 0xFFFFFFFF
+#define OPT_NATIVE_CALL_STACK 0x1
+
typedef struct {
uint8_t *base;
int32_t *offsets;