changeset 155:94a65fb4e1c7

Don't use the native call stack for M68K calls by default
author Mike Pavone <pavone@retrodev.com>
date Fri, 04 Jan 2013 23:21:07 -0800
parents 4791c0204410
children 3900cfde9dbb
files m68k_to_x86.c m68k_to_x86.h
diffstat 2 files changed, 88 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Fri Jan 04 22:51:01 2013 -0800
+++ b/m68k_to_x86.c	Fri Jan 04 23:21:07 2013 -0800
@@ -1398,7 +1398,9 @@
 	//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 @@
 	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;
 	}
-	dst = call(dst, (char *)dest_addr);
-	//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(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);
+	}
 	return dst;
 }
 
@@ -1725,7 +1731,9 @@
 	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 @@
 			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 @@
 			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 @@
 			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;
 			}
-			dst = call(dst, (char *)dest_addr);
+			if (opts->flags & OPT_NATIVE_CALL_STACK) {
+				dst = call(dst, (char *)dest_addr);
+			} else {
+				dst = jmp(dst, 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);
+			}
 		}
-		//would add_ir(dst, 8, RSP, SZ_Q) be faster here?
-		dst = pop_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);
+		}
 		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 @@
 			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 @@
 			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;
 			}
-			dst = call(dst, (char *)dest_addr);
+			if (opts->flags & OPT_NATIVE_CALL_STACK) {
+				dst = call(dst, (char *)dest_addr);
+			} else {
+				dst = jmp(dst, 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);
+			}
 		}
-		//would add_ir(dst, 8, RSP, SZ_Q) be faster here?
-		dst = pop_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);
+		}
 		break;
 	default:
 		m68k_disasm(inst, disasm_buf);
@@ -1902,10 +1950,15 @@
 	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;
 }
 
--- a/m68k_to_x86.h	Fri Jan 04 22:51:01 2013 -0800
+++ b/m68k_to_x86.h	Fri Jan 04 23:21:07 2013 -0800
@@ -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;