changeset 899:07bfbbbb4b2e

Fix for Z80 retranslation post alignment rework
author Michael Pavone <pavone@retrodev.com>
date Thu, 26 Nov 2015 22:30:41 -0800
parents 2f1157f00dc6
children 30efd12b1be1
files gen_x86.c gen_x86.h z80_to_x86.c
diffstat 3 files changed, 28 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/gen_x86.c	Thu Nov 26 00:10:36 2015 -0800
+++ b/gen_x86.c	Thu Nov 26 22:30:41 2015 -0800
@@ -1968,15 +1968,8 @@
 	code->cur = out;
 }
 
-void call(code_info *code, code_ptr fun)
+void call_noalign(code_info *code, code_ptr fun)
 {
-	code->stack_off += sizeof(void *);
-	int32_t adjust = 0;
-	if (code->stack_off & 0xF) {
-		adjust = 16 - (code->stack_off & 0xF);
-		code->stack_off += adjust;
-		sub_ir(code, adjust, RSP, SZ_PTR);
-	}
 	check_alloc_code(code, 5);
 	code_ptr out = code->cur;
 	ptrdiff_t disp = fun-(out+5);
@@ -1994,12 +1987,24 @@
 		fatal_error("call: %p - %p = %lX which is out of range for a 32-bit displacement\n", fun, out + 5, (long)disp);
 	}
 	code->cur = out;
+}
+
+
+void call(code_info *code, code_ptr fun)
+{
+	code->stack_off += sizeof(void *);
+	int32_t adjust = 0;
+	if (code->stack_off & 0xF) {
+		adjust = 16 - (code->stack_off & 0xF);
+		code->stack_off += adjust;
+		sub_ir(code, adjust, RSP, SZ_PTR);
+	}
+	call_noalign(code, fun);
 	if (adjust) {
 		add_ir(code, adjust, RSP, SZ_PTR);
 	}
 	code->stack_off -= sizeof(void *) + adjust;
 }
-
 void call_raxfallback(code_info *code, code_ptr fun)
 {
 	check_alloc_code(code, 5);
--- a/gen_x86.h	Thu Nov 26 00:10:36 2015 -0800
+++ b/gen_x86.h	Thu Nov 26 22:30:41 2015 -0800
@@ -210,6 +210,7 @@
 void btc_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size);
 void jcc(code_info *code, uint8_t cc, code_ptr dest);
 void jmp_rind(code_info *code, uint8_t dst);
+void call_noalign(code_info *code, code_ptr fun);
 void call_r(code_info *code, uint8_t dst);
 void retn(code_info *code);
 void cdq(code_info *code);
--- a/z80_to_x86.c	Thu Nov 26 00:10:36 2015 -0800
+++ b/z80_to_x86.c	Thu Nov 26 22:30:41 2015 -0800
@@ -2095,7 +2095,7 @@
 	uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address);
 	if (inst_start != INVALID_INSTRUCTION_START) {
 		code_ptr dst = z80_get_native_address(context, inst_start);
-		code_info code = {dst, dst+16};
+		code_info code = {dst, dst+32, 0};
 		z80_options * opts = context->options;
 		dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code.cur, inst_start, address);
 		mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D);
@@ -2536,13 +2536,24 @@
 
 	options->retrans_stub = code->cur;
 	tmp_stack_off = code->stack_off;
+	//calculate size of patch
+	mov_ir(code, 0x7FFF, options->gen.scratch1, SZ_D);
+	code->stack_off += sizeof(void *);
+	if (code->stack_off & 0xF) {
+		sub_ir(code, 16 - (code->stack_off & 0xF), RSP, SZ_PTR);
+	}
+	call_noalign(code, options->retrans_stub);
+	uint32_t patch_size = code->cur - options->retrans_stub;
+	code->cur = options->retrans_stub;
+	code->stack_off = tmp_stack_off;
+	
 	//pop return address
 	pop_r(code, options->gen.scratch2);
 	add_ir(code, 16-sizeof(void*), RSP, SZ_PTR);
 	code->stack_off = tmp_stack_off;
 	call(code, options->gen.save_context);
 	//adjust pointer before move and call instructions that got us here
-	sub_ir(code, options->gen.scratch1 >= R8 ? 11 : 10, options->gen.scratch2, SZ_PTR);
+	sub_ir(code, patch_size, options->gen.scratch2, SZ_PTR);
 	push_r(code, options->gen.context_reg);
 	call_args(code, (code_ptr)z80_retranslate_inst, 3, options->gen.scratch1, options->gen.context_reg, options->gen.scratch2);
 	pop_r(code, options->gen.context_reg);