# HG changeset patch # User Mike Pavone # Date 1372134745 25200 # Node ID 9fb111b5641f2b69cddedd65bee21f722cffd9ef # Parent d1bf9734ce94de669ecdec15bd2c39e93dea85b4 Fix access to int_enable_cycle in EI diff -r d1bf9734ce94 -r 9fb111b5641f gen_x86.c --- a/gen_x86.c Mon Jun 24 21:30:38 2013 -0700 +++ b/gen_x86.c Mon Jun 24 21:32:25 2013 -0700 @@ -517,6 +517,54 @@ return out; } +uint8_t * x86_irdisp32(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int32_t disp, uint8_t size) +{ + uint8_t sign_extend = 0; + if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { + sign_extend = 1; + opcode |= BIT_DIR; + } + if (size == SZ_W) { + *(out++) = PRE_SIZE; + } + + if (size == SZ_Q || dst >= R8) { + *out = PRE_REX; + if (size == SZ_Q) { + *out |= REX_QUAD; + } + if (dst >= R8) { + *out |= REX_RM_FIELD; + dst -= (R8 - X86_R8); + } + out++; + } + if (size != SZ_B) { + opcode |= BIT_SIZE; + } + *(out++) = opcode; + *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); + *(out++) = disp; + disp >>= 8; + *(out++) = disp; + disp >>= 8; + *(out++) = disp; + disp >>= 8; + *(out++) = disp; + *(out++) = val; + if (size != SZ_B && !sign_extend) { + val >>= 8; + *(out++) = val; + if (size != SZ_W) { + val >>= 8; + *(out++) = val; + val >>= 8; + *(out++) = val; + } + } + return out; +} + uint8_t * x86_shiftrot_ir(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size) { @@ -781,6 +829,11 @@ return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size); } +uint8_t * add_irdisp32(uint8_t * out, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size) +{ + return x86_irdisp32(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size); +} + uint8_t * add_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) { return x86_rrdisp8_sizedir(out, OP_ADD, src, dst_base, disp, size, 0); diff -r d1bf9734ce94 -r 9fb111b5641f z80_to_x86.c --- a/z80_to_x86.c Mon Jun 24 21:30:38 2013 -0700 +++ b/z80_to_x86.c Mon Jun 24 21:32:25 2013 -0700 @@ -901,11 +901,11 @@ break; case Z80_EI: dst = zcycles(dst, 4); - dst = mov_rrdisp8(dst, ZCYCLES, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D); + dst = mov_rrdisp32(dst, ZCYCLES, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D); dst = mov_irdisp8(dst, 1, CONTEXT, offsetof(z80_context, iff1), SZ_B); dst = mov_irdisp8(dst, 1, CONTEXT, offsetof(z80_context, iff2), SZ_B); //interrupt enable has a one-instruction latency, minimum instruction duration is 4 cycles - dst = add_irdisp8(dst, 4, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D); + dst = add_irdisp32(dst, 4, CONTEXT, offsetof(z80_context, int_enable_cycle), SZ_D); dst = call(dst, (uint8_t *)z80_do_sync); break; case Z80_IM: