changeset 216:0b5ec22dcda2

Fix some bugs related to sign-extension of address registers and pre-decrement amount for a7 when used as a source.
author Mike Pavone <pavone@retrodev.com>
date Fri, 19 Apr 2013 21:36:54 -0700
parents 2b1c2c28b261
children acd29e2664c6
files m68k_to_x86.c
diffstat 1 files changed, 17 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Fri Apr 19 21:36:00 2013 -0700
+++ b/m68k_to_x86.c	Fri Apr 19 21:36:54 2013 -0700
@@ -137,7 +137,7 @@
 		}
 		break;
 	case MODE_AREG_PREDEC:
-		dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : 1);
+		dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 :1));
 		out = cycles(out, PREDEC_PENALTY);
 		if (opts->aregs[inst->src.params.regs.pri] >= 0) {
 			out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D);
@@ -354,6 +354,9 @@
 		}
 		ea->mode = MODE_IMMED;
 		ea->disp = inst->src.params.immed;
+		if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD && ea->disp & 0x8000) {
+			ea->disp |= 0xFFFF0000;
+		}
 		return out;
 	default:
 		m68k_disasm(inst, disasm_buf);
@@ -805,19 +808,21 @@
 		dst = mov_ir(dst, 0, FLAG_C, SZ_B);
 	}
 	
-	if (src.mode == MODE_REG_DIRECT) {
-		flags_reg = src.base;
-	} else {
-		if (reg >= 0) {
-			flags_reg = reg;
+	if (inst->dst.addr_mode != MODE_AREG) {
+		if (src.mode == MODE_REG_DIRECT) {
+			flags_reg = src.base;
 		} else {
-			if(src.mode == MODE_REG_DISPLACE8) {
-				dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size);
+			if (reg >= 0) {
+				flags_reg = reg;
 			} else {
-				dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
+				if(src.mode == MODE_REG_DISPLACE8) {
+					dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size);
+				} else {
+					dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size);
+				}
+				src.mode = MODE_REG_DIRECT;
+				flags_reg = src.base = SCRATCH1;
 			}
-			src.mode = MODE_REG_DIRECT;
-			flags_reg = src.base = SCRATCH1;
 		}
 	}
 	uint8_t size = inst->extra.size;
@@ -3879,7 +3884,7 @@
 			uint8_t * after = translate_m68k(dst, &instbuf, opts);
 			map_native_address(context, instbuf.address, dst, m68k_size, after-dst);
 			dst = after;
-		} while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_INVALID && instbuf.op != M68K_TRAP && instbuf.op != M68K_RTS && instbuf.op != M68K_RTR && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP);
+		} while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_RESET && instbuf.op != M68K_INVALID && instbuf.op != M68K_TRAP && instbuf.op != M68K_RTS && instbuf.op != M68K_RTR && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP);
 		process_deferred(opts);
 		if (opts->deferred) {
 			address = opts->deferred->address;