changeset 539:c2716b502a81

Generate save_context and load_context functions at runtime
author Michael Pavone <pavone@retrodev.com>
date Fri, 14 Feb 2014 19:56:18 -0800
parents 71b7cf543040
children 4ca826862174
files m68k_to_x86.c m68k_to_x86.h
diffstat 2 files changed, 63 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Thu Feb 13 21:34:50 2014 -0800
+++ b/m68k_to_x86.c	Fri Feb 14 19:56:18 2014 -0800
@@ -31,8 +31,6 @@
 m68k_context * sync_components(m68k_context * context, uint32_t address);
 
 void handle_cycle_limit();
-void m68k_save_context();
-void m68k_load_context();
 void m68k_modified_ret_addr();
 void m68k_native_addr();
 void m68k_native_addr_and_sync();
@@ -3286,7 +3284,7 @@
 		}
 		break;
 	case M68K_ILLEGAL:
-		dst = call(dst, (uint8_t *)m68k_save_context);
+		dst = call(dst, opts->save_context);
 		dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
 		dst = call(dst, (uint8_t *)print_regs_exit);
 		break;
@@ -3513,7 +3511,7 @@
 		}
 		break;
 	case M68K_RESET:
-		dst = call(dst, (uint8_t *)m68k_save_context);
+		dst = call(dst, opts->save_context);
 		dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
 		dst = call(dst, (uint8_t *)print_regs_exit);
 		break;
@@ -4136,14 +4134,14 @@
 		dst = bp_stub;
 
 		//Save context and call breakpoint handler
-		dst = call(dst, (uint8_t *)m68k_save_context);
+		dst = call(dst, opts->save_context);
 		dst = push_r(dst, SCRATCH1);
 		dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
 		dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
 		dst = call(dst, bp_handler);
 		dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
 		//Restore context
-		dst = call(dst, (uint8_t *)m68k_load_context);
+		dst = call(dst, opts->load_context);
 		dst = pop_r(dst, SCRATCH1);
 		//do prologue stuff
 		dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
@@ -4240,7 +4238,7 @@
 					dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_Q);
 					uint8_t * not_null = dst+1;
 					dst = jcc(dst, CC_NZ, dst+2);
-					dst = call(dst, (uint8_t *)m68k_save_context);
+					dst = call(dst, opts->save_context);
 					if (is_write) {
 						//SCRATCH2 is RDI, so no need to move it there
 						dst = mov_rr(dst, SCRATCH1, RDX, size);
@@ -4265,7 +4263,7 @@
 						dst = pop_r(dst, CONTEXT);
 						dst = mov_rr(dst, RAX, SCRATCH1, size);
 					}
-					dst = jmp(dst, (uint8_t *)m68k_load_context);
+					dst = jmp(dst, opts->load_context);
 
 					*not_null = dst - (not_null + 1);
 				}
@@ -4335,15 +4333,15 @@
 				dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D);
 				uint8_t * not_code = dst+1;
 				dst = jcc(dst, CC_NC, dst+2);
-				dst = call(dst, (uint8_t *)m68k_save_context);
+				dst = call(dst, opts->save_context);
 				dst = call(dst, (uint8_t *)m68k_handle_code_write);
 				dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
-				dst = call(dst, (uint8_t *)m68k_load_context);
+				dst = call(dst, opts->load_context);
 				*not_code = dst - (not_code+1);
 			}
 			dst = retn(dst);
 		} else if (cfun) {
-			dst = call(dst, (uint8_t *)m68k_save_context);
+			dst = call(dst, opts->save_context);
 			if (is_write) {
 				//SCRATCH2 is RDI, so no need to move it there
 				dst = mov_rr(dst, SCRATCH1, RDX, size);
@@ -4368,7 +4366,7 @@
 				dst = pop_r(dst, CONTEXT);
 				dst = mov_rr(dst, RAX, SCRATCH1, size);
 			}
-			dst = jmp(dst, (uint8_t *)m68k_load_context);
+			dst = jmp(dst, opts->load_context);
 		} else {
 			//Not sure the best course of action here
 			if (!is_write) {
@@ -4406,6 +4404,12 @@
 	opts->aregs[1] = R14;
 	opts->aregs[2] = R9;
 	opts->aregs[7] = R15;
+
+	opts->flag_regs[0] = -1;
+	opts->flag_regs[1] = RBX;
+	opts->flag_regs[2] = RDX;
+	opts->flag_regs[3] = BH;
+	opts->flag_regs[4] = DH;
 	opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
 	memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
 	opts->deferred = NULL;
@@ -4415,12 +4419,51 @@
 	opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64);
 	memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64);
 
+	uint8_t * dst = opts->cur_code;
+
+	opts->save_context = dst;
+	for (int i = 0; i < 5; i++)
+		if (opts->flag_regs[i] >= 0) {
+			dst = mov_rrdisp8(dst, opts->flag_regs[i], CONTEXT, offsetof(m68k_context, flags) + i, SZ_B);
+		}
+	for (int i = 0; i < 8; i++)
+	{
+		if (opts->dregs[i] >= 0) {
+			dst = mov_rrdisp8(dst, opts->dregs[i], CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, SZ_D);
+		}
+		if (opts->aregs[i] >= 0) {
+			dst = mov_rrdisp8(dst, opts->aregs[i], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, SZ_D);
+		}
+	}
+	dst = mov_rrdisp8(dst, CYCLES, CONTEXT, offsetof(m68k_context, current_cycle), SZ_D);
+	dst = retn(dst);
+
+	opts->load_context = dst;
+	for (int i = 0; i < 5; i++)
+		if (opts->flag_regs[i] >= 0) {
+			dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B);
+		}
+	for (int i = 0; i < 8; i++)
+	{
+		if (opts->dregs[i] >= 0) {
+			dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, opts->dregs[i], SZ_D);
+		}
+		if (opts->aregs[i] >= 0) {
+			dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D);
+		}
+	}
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, current_cycle), CYCLES, SZ_D);
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, target_cycle), LIMIT, SZ_D);
+	dst = retn(dst);
+
+	opts->cur_code = dst;
+
 	opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16);
 	opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8);
 	opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16);
 	opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8);
 
-	uint8_t * dst = opts->cur_code;
+	dst = opts->cur_code;
 
 	opts->read_32 = dst;
 	dst = push_r(dst, SCRATCH1);
@@ -4463,7 +4506,7 @@
 	dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
 	uint8_t * skip_sync = dst+1;
 	dst = jcc(dst, CC_C, dst+2);
-	dst = call(dst, (uint8_t *)m68k_save_context);
+	dst = call(dst, opts->save_context);
 	dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
 	dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
 	dst = test_ir(dst, 8, RSP, SZ_D);
@@ -4478,7 +4521,7 @@
 	dst = add_ir(dst, 8, RSP, SZ_Q);
 	*no_adjust = dst - (no_adjust+1);
 	dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
-	dst = jmp(dst, (uint8_t *)m68k_load_context);
+	dst = jmp(dst, opts->load_context);
 	*skip_sync = dst - (skip_sync+1);
 	dst = retn(dst);
 	*do_int = dst - (do_int+1);
--- a/m68k_to_x86.h	Thu Feb 13 21:34:50 2014 -0800
+++ b/m68k_to_x86.h	Fri Feb 14 19:56:18 2014 -0800
@@ -1,6 +1,6 @@
 /*
  Copyright 2013 Michael Pavone
- This file is part of BlastEm. 
+ This file is part of BlastEm.
  BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
 */
 #ifndef M68K_TO_X86_H_
@@ -22,6 +22,7 @@
 	uint32_t        flags;
 	int8_t          dregs[8];
 	int8_t          aregs[8];
+	int8_t			flag_regs[5];
 	native_map_slot *native_code_map;
 	deferred_addr   *deferred;
 	uint8_t         *cur_code;
@@ -37,6 +38,8 @@
 	uint8_t         *write_32_highfirst;
 	uint8_t         *handle_cycle_limit_int;
 	uint8_t         *trap;
+	uint8_t			*save_context;
+	uint8_t			*load_context;
 } x86_68k_options;
 
 typedef struct {
@@ -53,7 +56,7 @@
 	uint16_t        *mem_pointers[NUM_MEM_AREAS];
 	void            *video_context;
 	uint16_t        reserved;
-	
+
 	native_map_slot *native_code_map;
 	void            *options;
 	uint8_t         ram_code_flags[32/8];