changeset 1465:5d41d0574863

Preserve original address when retranslating instructions instead of switching to the lowest alias
author Michael Pavone <pavone@retrodev.com>
date Wed, 13 Sep 2017 21:06:25 -0700
parents ffe45c5b8390
children f2ee46d08b01
files backend.h backend_x86.c gen_x86.c gen_x86.h m68k_core_x86.c
diffstat 5 files changed, 58 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/backend.h	Fri Sep 08 00:38:22 2017 -0700
+++ b/backend.h	Wed Sep 13 21:06:25 2017 -0700
@@ -98,6 +98,8 @@
 	uint32_t           max_address;
 	uint32_t           bus_cycles;
 	uint32_t           clock_divider;
+	uint32_t           move_pc_off;
+	uint32_t           move_pc_size;
 	int32_t            mem_ptr_off;
 	int32_t            ram_flags_off;
 	uint8_t            ram_flags_shift;
@@ -123,6 +125,9 @@
 void check_code_prologue(code_info *code);
 void log_address(cpu_options *opts, uint32_t address, char * format);
 
+void retranslate_calc(cpu_options *opts);
+void patch_for_retranslate(cpu_options *opts, code_ptr native_address, code_ptr handler);
+
 code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc);
 void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
 uint16_t read_word(uint32_t address, void **mem_pointers, cpu_options *opts, void *context);
--- a/backend_x86.c	Fri Sep 08 00:38:22 2017 -0700
+++ b/backend_x86.c	Wed Sep 13 21:06:25 2017 -0700
@@ -1,5 +1,6 @@
 #include "backend.h"
 #include "gen_x86.h"
+#include <string.h>
 
 void cycles(cpu_options *opts, uint32_t num)
 {
@@ -28,6 +29,41 @@
 	*jmp_off = code->cur - (jmp_off+1);
 }
 
+void retranslate_calc(cpu_options *opts)
+{
+	code_info *code = &opts->code;
+	code_info tmp = *code;
+	uint8_t cc;
+	if (opts->limit < 0) {
+		cmp_ir(code, 1, opts->cycles, SZ_D);
+		cc = CC_NS;
+	} else {
+		cmp_rr(code, opts->cycles, opts->limit, SZ_D);
+		cc = CC_A;
+	}
+	jcc(code, cc, code->cur+2);
+	opts->move_pc_off = code->cur - tmp.cur;
+	mov_ir(code, 0x1234, opts->scratch1, SZ_D);
+	opts->move_pc_size = code->cur - tmp.cur - opts->move_pc_off;
+	*code = tmp;
+}
+
+void patch_for_retranslate(cpu_options *opts, code_ptr native_address, code_ptr handler)
+{
+	if (!is_mov_ir(native_address)) {
+		//instruction is not already patched for either retranslation or a breakpoint
+		//copy original mov_ir instruction containing PC to beginning of native code area
+		memmove(native_address, native_address + opts->move_pc_off, opts->move_pc_size);
+	}
+	//jump to the retranslation handler
+	code_info tmp = {
+		.cur =  native_address + opts->move_pc_size,
+		.last = native_address + 256,
+		.stack_off = 0
+	};
+	jmp(&tmp, handler);
+}
+
 void check_cycles(cpu_options * opts)
 {
 	code_info *code = &opts->code;
--- a/gen_x86.c	Fri Sep 08 00:38:22 2017 -0700
+++ b/gen_x86.c	Wed Sep 13 21:06:25 2017 -0700
@@ -1307,6 +1307,15 @@
 	code->cur = out;
 }
 
+uint8_t is_mov_ir(code_ptr inst)
+{
+	while (*inst == PRE_SIZE || *inst == PRE_REX)
+	{
+		inst++;
+	}
+	return (*inst & 0xF8) == OP_MOV_I8R || (*inst & 0xF8) == OP_MOV_IR || (*inst & 0xFE) == OP_MOV_IEA;
+}
+
 void mov_irdisp(code_info *code, int32_t val, uint8_t dst, int32_t disp, uint8_t size)
 {
 	check_alloc_code(code, 12);
--- a/gen_x86.h	Fri Sep 08 00:38:22 2017 -0700
+++ b/gen_x86.h	Wed Sep 13 21:06:25 2017 -0700
@@ -216,6 +216,7 @@
 void retn(code_info *code);
 void cdq(code_info *code);
 void loop(code_info *code, code_ptr dst);
+uint8_t is_mov_ir(code_ptr inst);
 
 #endif //GEN_X86_H_
 
--- a/m68k_core_x86.c	Fri Sep 08 00:38:22 2017 -0700
+++ b/m68k_core_x86.c	Wed Sep 13 21:06:25 2017 -0700
@@ -2498,11 +2498,8 @@
 	m68k_options * options = context->options;
 	uint32_t inst_start = get_instruction_start(options, address);
 	while (inst_start && (address - inst_start) < M68K_MAX_INST_SIZE) {
-		code_info *code = &options->gen.code;
 		code_ptr dst = get_native_address(context->options, inst_start);
-		code_info orig = {dst, dst + 128, 0};
-		mov_ir(&orig, inst_start, options->gen.scratch2, SZ_D);
-		jmp(&orig, options->retrans_stub);
+		patch_for_retranslate(&options->gen, dst, options->retrans_stub);
 		inst_start = get_instruction_start(options, inst_start - 2);
 	}
 	return context;
@@ -2531,12 +2528,13 @@
 			for (uint32_t offset = start_offset; offset < end_offset; offset++)
 			{
 				if (native_code_map[chunk].offsets[offset] != INVALID_OFFSET && native_code_map[chunk].offsets[offset] != EXTENSION_WORD) {
-					code_info code;
+					patch_for_retranslate(&opts->gen, native_code_map[chunk].base + native_code_map[chunk].offsets[offset], opts->retrans_stub);
+					/*code_info code;
 					code.cur = native_code_map[chunk].base + native_code_map[chunk].offsets[offset];
 					code.last = code.cur + 32;
 					code.stack_off = 0;
 					mov_ir(&code, chunk * NATIVE_CHUNK_SIZE + offset, opts->gen.scratch2, SZ_D);
-					jmp(&code, opts->retrans_stub);
+					jmp(&code, opts->retrans_stub);*/
 				}
 			}
 		}
@@ -3182,7 +3180,7 @@
 	opts->retrans_stub = code->cur;
 	call(code, opts->gen.save_context);
 	push_r(code, opts->gen.context_reg);
-	call_args(code,(code_ptr)m68k_retranslate_inst, 2, opts->gen.scratch2, opts->gen.context_reg);
+	call_args(code,(code_ptr)m68k_retranslate_inst, 2, opts->gen.scratch1, opts->gen.context_reg);
 	pop_r(code, opts->gen.context_reg);
 	mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR);
 	call(code, opts->gen.load_context);
@@ -3225,4 +3223,6 @@
 	add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR);
 	jmp_r(code, opts->gen.scratch1);
 	code->stack_off = tmp_stack_off;
+	
+	retranslate_calc(&opts->gen);
 }