changeset 1224:15c5be05e6a9

Ported correct but inefficient overlapping instruction handling from 68K core to Z80 core. Fixed remaining stack alignment issue for Z80 breakpoints on 64-bit. Probably still needs fixing for 32-bit
author Michael Pavone <pavone@retrodev.com>
date Sun, 19 Feb 2017 12:41:57 -0800
parents a477cc22a960
children 197cb199a35b
files z80_to_x86.c
diffstat 1 files changed, 13 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/z80_to_x86.c	Sat Feb 18 05:42:37 2017 -0800
+++ b/z80_to_x86.c	Sun Feb 19 12:41:57 2017 -0800
@@ -2959,8 +2959,10 @@
 			memset(map->offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE);
 		}
 	
-		//TODO: better handling of potentially overlapping instructions
-		map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD;
+		if (map->offsets[address % NATIVE_CHUNK_SIZE] == INVALID_OFFSET) {
+			//TODO: better handling of potentially overlapping instructions
+			map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD;
+		}
 	}
 }
 
@@ -2993,16 +2995,20 @@
 	return address;
 }
 
+//Technically unbounded due to redundant prefixes, but this is the max useful size
+#define Z80_MAX_INST_SIZE 4
+
 z80_context * z80_handle_code_write(uint32_t address, z80_context * context)
 {
 	uint32_t inst_start = z80_get_instruction_start(context, address);
-	if (inst_start != INVALID_INSTRUCTION_START) {
+	while (inst_start != INVALID_INSTRUCTION_START && (address - inst_start) < Z80_MAX_INST_SIZE) {
 		code_ptr dst = z80_get_native_address(context, inst_start);
 		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);
 		call(&code, opts->retrans_stub);
+		inst_start = z80_get_instruction_start(context, inst_start - 1);
 	}
 	return context;
 }
@@ -3712,7 +3718,7 @@
 
 void zcreate_stub(z80_context * context)
 {
-	//FIXME: Stack offset stuff is still a bit broken
+	//FIXME: Stack offset stuff is probably broken on 32-bit
 	z80_options * opts = context->options;
 	code_info *code = &opts->gen.code;
 	uint32_t start_stack_off = code->stack_off;
@@ -3744,6 +3750,9 @@
 	jcc(code, CC_NS, code->cur + 7);
 	pop_r(code, opts->gen.scratch1);
 	add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR);
+#ifdef X86_64
+	sub_ir(code, 8, RSP, SZ_PTR);
+#endif
 	push_r(code, opts->gen.scratch1);
 	jmp(code, opts->gen.handle_cycle_limit_int);
 	*jmp_off = code->cur - (jmp_off+1);