changeset 547:3090d016c9e9

Generate get_sr, set_sr and set_ccr at runtime so they can respect the flag_regs setting
author Michael Pavone <pavone@retrodev.com>
date Tue, 18 Feb 2014 20:32:10 -0800
parents 90aca661542b
children a3afee2271ce
files m68k_to_x86.c m68k_to_x86.h runtime.S
diffstat 3 files changed, 69 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Mon Feb 17 19:58:37 2014 -0800
+++ b/m68k_to_x86.c	Tue Feb 18 20:32:10 2014 -0800
@@ -40,9 +40,6 @@
 m68k_context * sync_components(m68k_context * context, uint32_t address);
 
 void m68k_invalid();
-void set_sr();
-void set_ccr();
-void get_sr();
 void bcd_add();
 void bcd_sub();
 
@@ -3379,7 +3376,7 @@
 		break;
 	case M68K_MOVE_FROM_SR:
 		//TODO: Trap if not in system mode
-		dst = call(dst, (uint8_t *)get_sr);
+		dst = call(dst, opts->get_sr);
 		if (dst_op.mode == MODE_REG_DIRECT) {
 			dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_W);
 		} else {
@@ -3415,7 +3412,7 @@
 					dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W);
 				}
 			}
-			dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr));
+			dst = call(dst, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr);
 			dst = cycles(dst, 12);
 
 		}
@@ -3834,7 +3831,7 @@
 		dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
 		dst = call(dst, opts->read_16);
 		dst = add_ir(dst, 2, opts->aregs[7], SZ_D);
-		dst = call(dst, (uint8_t *)set_sr);
+		dst = call(dst, opts->set_sr);
 		//Read saved PC
 		dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
 		dst = call(dst, opts->read_32);
@@ -3856,7 +3853,7 @@
 		dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
 		dst = call(dst, opts->read_16);
 		dst = add_ir(dst, 2, opts->aregs[7], SZ_D);
-		dst = call(dst, (uint8_t *)set_ccr);
+		dst = call(dst, opts->set_ccr);
 		//Read saved PC
 		dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
 		dst = call(dst, opts->read_32);
@@ -4724,6 +4721,66 @@
 	dst = add_ir(dst, 2, SCRATCH2, SZ_D);
 	dst = jmp(dst, opts->write_16);
 
+	opts->get_sr = dst;
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, status), SCRATCH1, SZ_B);
+	dst = shl_ir(dst, 8, SCRATCH1, SZ_W);
+	if (opts->flag_regs[FLAG_X] >= 0) {
+		dst = mov_rr(dst, opts->flag_regs[FLAG_X], SCRATCH1, SZ_B);
+	} else {
+		int8_t offset = offsetof(m68k_context, flags);
+		if (offset) {
+			dst = mov_rdisp8r(dst, CONTEXT, offset, SCRATCH1, SZ_B);
+		} else {
+			dst = mov_rindr(dst, CONTEXT, SCRATCH1, SZ_B);
+		}
+	}
+	for (int flag = FLAG_N; flag <= FLAG_C; flag++)
+	{
+		dst = shl_ir(dst, 1, SCRATCH1, SZ_B);
+		if (opts->flag_regs[flag] >= 0) {
+			dst = or_rr(dst, opts->flag_regs[flag], SCRATCH1, SZ_B);
+		} else {
+			dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, SCRATCH1, SZ_B);
+		}
+	}
+	dst = retn(dst);
+
+	opts->set_sr = dst;
+	for (int flag = FLAG_C; flag >= FLAG_X; flag--)
+	{
+		dst = rcr_ir(dst, 1, SCRATCH1, SZ_B);
+		if (opts->flag_regs[flag] >= 0) {
+			dst = setcc_r(dst, CC_C, opts->flag_regs[flag]);
+		} else {
+			int8_t offset = offsetof(m68k_context, flags) + flag;
+			if (offset) {
+				dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset);
+			} else {
+				dst = setcc_rind(dst, CC_C, CONTEXT);
+			}
+		}
+	}
+	dst = shr_ir(dst, 8, SCRATCH1, SZ_W);
+	dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B);
+	dst = retn(dst);
+
+	opts->set_ccr = dst;
+	for (int flag = FLAG_C; flag >= FLAG_X; flag--)
+	{
+		dst = rcr_ir(dst, 1, SCRATCH1, SZ_B);
+		if (opts->flag_regs[flag] >= 0) {
+			dst = setcc_r(dst, CC_C, opts->flag_regs[flag]);
+		} else {
+			int8_t offset = offsetof(m68k_context, flags) + flag;
+			if (offset) {
+				dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset);
+			} else {
+				dst = setcc_rind(dst, CC_C, CONTEXT);
+			}
+		}
+	}
+	dst = retn(dst);
+
 	opts->handle_cycle_limit_int = dst;
 	dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
 	uint8_t * do_int = dst+1;
@@ -4766,7 +4823,7 @@
 	dst = call(dst, opts->write_32_lowfirst);
 	//save status register
 	dst = sub_ir(dst, 2, opts->aregs[7], SZ_D);
-	dst = call(dst, (uint8_t *)get_sr);
+	dst = call(dst, opts->get_sr);
 	dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
 	dst = call(dst, opts->write_16);
 	//update status register
@@ -4802,7 +4859,7 @@
 	dst = call(dst, opts->write_32_lowfirst);
 	//save status register
 	dst = sub_ir(dst, 2, opts->aregs[7], SZ_D);
-	dst = call(dst, (uint8_t *)get_sr);
+	dst = call(dst, opts->get_sr);
 	dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
 	dst = call(dst, opts->write_16);
 	//set supervisor bit
--- a/m68k_to_x86.h	Mon Feb 17 19:58:37 2014 -0800
+++ b/m68k_to_x86.h	Tue Feb 18 20:32:10 2014 -0800
@@ -46,6 +46,9 @@
 	uint8_t         *retrans_stub;
 	uint8_t         *native_addr;
 	uint8_t         *native_addr_and_sync;
+	uint8_t			*get_sr;
+	uint8_t			*set_sr;
+	uint8_t			*set_ccr;
 } x86_68k_options;
 
 typedef struct {
--- a/runtime.S	Mon Feb 17 19:58:37 2014 -0800
+++ b/runtime.S	Tue Feb 18 20:32:10 2014 -0800
@@ -70,56 +70,5 @@
 	mov %rdi, %rax
 	ret
 
-	.global get_sr
-get_sr:
-	mov 5(%rsi), %cl
-	shl $8, %cx
-	mov (%rsi), %cl
-	shl $1, %cl
-	or %bl, %cl
-	shl $1, %cl
-	or %dl, %cl
-	shl $1, %cl
-	or %bh, %cl
-	shl $1, %cl
-	or %dh, %cl
-	ret
 
-	.global set_sr
-set_sr:
-	mov %cl, %dh
-	and $1, %dh
-	shr $1, %cl
-	mov %cl, %bh
-	and $1, %bh
-	shr $1, %cl
-	mov %cl, %dl
-	and $1, %dl
-	shr $1, %cl
-	mov %cl, %bl
-	and $1, %bl
-	shr $1, %cl
-	and $1, %cl
-	mov %cl, (%rsi)
-	shr $8, %cx
-	mov %cl, 5(%rsi)
-	ret
 
-	.global set_ccr
-set_ccr:
-	mov %cl, %dh
-	and $1, %dh
-	shr $1, %cl
-	mov %cl, %bh
-	and $1, %bh
-	shr $1, %cl
-	mov %cl, %dl
-	and $1, %dl
-	shr $1, %cl
-	mov %cl, %bl
-	and $1, %bl
-	shr $1, %cl
-	and $1, %cl
-	mov %cl, (%rsi)
-	ret
-