diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-17 11:17:49 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-17 11:17:49 +0100 |
| commit | e8d2b6d25d3718355bc2cd5c30fcab74e81eeb8b (patch) | |
| tree | bae54424b4ff21e9f935dcd1ce668495fe571a3b | |
| parent | d1a037b38b647ac54c11a1b1e00a800205193ada (diff) | |
| download | box64-e8d2b6d25d3718355bc2cd5c30fcab74e81eeb8b.tar.gz box64-e8d2b6d25d3718355bc2cd5c30fcab74e81eeb8b.zip | |
Excplicit handling of bit size for defered flags
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_emit_math.c | 17 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_emit_tests.c | 2 | ||||
| -rwxr-xr-x | src/emu/x64emu_private.h | 13 | ||||
| -rwxr-xr-x | src/emu/x64primop.h | 334 | ||||
| -rwxr-xr-x | src/emu/x64run_private.c | 649 | ||||
| -rwxr-xr-x | src/include/regs.h | 3 |
7 files changed, 518 insertions, 502 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 98f339e9..f15d9f85 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -119,6 +119,8 @@ if(((uint64_t)(imm64))&0xffff000000000000L) {MOVKx_LSL(Rd, (((uint64_t)(imm64))>>48)&0xffff, 48);} \ } +#define MOV64xw(Rd, imm64) if(rex.w) {MOV64x(Rd, imm64);} else {MOV32w(Rd, imm64);} + // ADD / SUB #define ADDSUB_REG_gen(sf, op, S, shift, Rm, imm6, Rn, Rd) ((sf)<<31 | (op)<<30 | (S)<<29 | 0b01011<<24 | (shift)<<22 | (Rm)<<16 | (imm6)<<10 | (Rn)<<5 | (Rd)) diff --git a/src/dynarec/dynarec_arm64_emit_math.c b/src/dynarec/dynarec_arm64_emit_math.c index d83187f2..0c20e331 100755 --- a/src/dynarec/dynarec_arm64_emit_math.c +++ b/src/dynarec/dynarec_arm64_emit_math.c @@ -219,26 +219,21 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in if(c>=0 && c<0x1000) { SUBxw_U12(s1, s1, c); } else { - MOV64x(s5, c); + MOV64xw(s5, c); SUBxw_REG(s1, s1, s5); } return; } IFX(X_PEND) { - if(rex.w) { - STRx_U12(s1, xEmu, offsetof(x64emu_t, op1)); - } else { - MOVw(s3, s1); - STRx_U12(s3, xEmu, offsetof(x64emu_t, op1)); - } - MOV64x(s3, c); - STRx_U12(s3, xEmu, offsetof(x64emu_t, op2)); + STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1)); + MOV64xw(s3, c); + STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2)); SET_DF(s4, rex.w?d_sub64:d_sub32); } else IFX(X_ALL) { SET_DFNONE(s4); } IFX(X_AF) { - MOV64x(s5, c); + MOV64xw(s5, c); MVNxw(s4, s1); ORRxw_REG(s3, s4, s5); // s3 = ~op1 | op2 BICxw_REG(s4, s5, s1); // s4 = ~op1 & op2 @@ -258,7 +253,7 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in } } IFX(X_PEND) { - STRx_U12(s1, xEmu, offsetof(x64emu_t, res)); + STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_AF) { ANDxw_REG(s3, s3, s1); // s3 = (~op1 | op2) & res diff --git a/src/dynarec/dynarec_arm64_emit_tests.c b/src/dynarec/dynarec_arm64_emit_tests.c index 1c014b9f..f8352a32 100755 --- a/src/dynarec/dynarec_arm64_emit_tests.c +++ b/src/dynarec/dynarec_arm64_emit_tests.c @@ -310,7 +310,7 @@ void emit_test32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s } ANDSxw_REG(s3, s1, s2); // res = s1 & s2 IFX(X_PEND) { - STRx_U12(s3, xEmu, offsetof(x64emu_t, res)); + STRxw_U12(s3, xEmu, offsetof(x64emu_t, res)); } IFX(X_ZF) { Bcond(cNE, +8); diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h index 144a6f33..27bb60f1 100755 --- a/src/emu/x64emu_private.h +++ b/src/emu/x64emu_private.h @@ -18,6 +18,13 @@ typedef struct forkpty_s { void* f; // forkpty function } forkpty_t; +typedef union multiuint_s { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; +} multiuint_t; + typedef struct x64emu_s { // cpu reg64_t regs[16]; @@ -40,9 +47,9 @@ typedef struct x64emu_s { // defered flags int dummy1; // to align on 64bits with df defered_flags_t df; - uint64_t op1; - uint64_t op2; - uint64_t res; + multiuint_t op1; + multiuint_t op2; + multiuint_t res; uint32_t *x64emu_parity_tab; // helper #ifdef HAVE_TRACE uintptr_t prev2_ip; diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h index f27c8cc0..97264208 100755 --- a/src/emu/x64primop.h +++ b/src/emu/x64primop.h @@ -16,70 +16,70 @@ uint64_t adc64 (x64emu_t *emu, uint64_t d, uint64_t s); static inline uint8_t add8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->res = d + s; - emu->op1 = d; - emu->op2 = s; + emu->res.u16 = d + s; + emu->op1.u8 = d; + emu->op2.u8 = s; emu->df = d_add8; - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t add16(x64emu_t *emu, uint16_t d, uint16_t s) { - emu->res = d + s; - emu->op1 = d; - emu->op2 = s; + emu->res.u32 = d + s; + emu->op1.u16 = d; + emu->op2.u16 = s; emu->df = d_add16; - return (uint16_t)emu->res; + return emu->res.u16; } static inline uint32_t add32(x64emu_t *emu, uint32_t d, uint32_t s) { - emu->res = (uint64_t)d + s; - emu->op1 = d; - emu->op2 = s; + emu->res.u64 = (uint64_t)d + s; + emu->op1.u32 = d; + emu->op2.u32 = s; emu->df = d_add32; - return emu->res; + return emu->res.u32; } static inline uint64_t add64(x64emu_t *emu, uint64_t d, uint64_t s) { - emu->res = d + s; - emu->op1 = d; - emu->op2 = s; + emu->res.u64 = d + s; + emu->op1.u64 = d; + emu->op2.u64 = s; emu->df = d_add64; - return emu->res; + return emu->res.u64; } static inline uint8_t and8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->res = d & s; + emu->res.u8 = d & s; emu->df = d_and8; - return emu->res; + return emu->res.u8; } static inline uint16_t and16(x64emu_t *emu, uint16_t d, uint16_t s) { - emu->res = d & s; + emu->res.u16 = d & s; emu->df = d_and16; - return emu->res; + return emu->res.u16; } static inline uint32_t and32(x64emu_t *emu, uint32_t d, uint32_t s) { - emu->res = d & s; + emu->res.u32 = d & s; emu->df = d_and32; - return emu->res; + return emu->res.u32; } static inline uint64_t and64(x64emu_t *emu, uint64_t d, uint64_t s) { - emu->res = d & s; + emu->res.u64 = d & s; emu->df = d_and64; - return emu->res; + return emu->res.u64; } uint8_t cmp8 (x64emu_t *emu, uint8_t d, uint8_t s); @@ -91,146 +91,146 @@ uint8_t das8 (x64emu_t *emu, uint8_t d); static inline uint8_t dec8(x64emu_t *emu, uint8_t d) { - emu->res = d - 1; - emu->op1 = d; + emu->res.u8 = d - 1; + emu->op1.u8 = d; emu->df = d_dec8; - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t dec16(x64emu_t *emu, uint16_t d) { - emu->res = d - 1; - emu->op1 = d; + emu->res.u16 = d - 1; + emu->op1.u16 = d; emu->df = d_dec16; - return (uint16_t)emu->res; + return emu->res.u16; } static inline uint32_t dec32(x64emu_t *emu, uint32_t d) { - emu->res = d - 1; - emu->op1 = d; + emu->res.u32 = d - 1; + emu->op1.u32 = d; emu->df = d_dec32; - return emu->res; + return emu->res.u32; } static inline uint64_t dec64(x64emu_t *emu, uint64_t d) { - emu->res = d - 1; - emu->op1 = d; + emu->res.u64 = d - 1; + emu->op1.u64 = d; emu->df = d_dec64; - return emu->res; + return emu->res.u64; } static inline uint8_t inc8(x64emu_t *emu, uint8_t d) { - emu->res = d + 1; - emu->op1 = d; + emu->res.u8 = d + 1; + emu->op1.u8 = d; emu->df = d_inc8; - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t inc16(x64emu_t *emu, uint16_t d) { - emu->res = d + 1; - emu->op1 = d; + emu->res.u16 = d + 1; + emu->op1.u16 = d; emu->df = d_inc16; - return (uint16_t)emu->res; + return emu->res.u16; } static inline uint32_t inc32(x64emu_t *emu, uint32_t d) { if(emu->df == d_shr32) { // workaround for some wine trickery - uint32_t cnt = emu->op2; + uint32_t cnt = emu->op2.u32; if (cnt > 0) { - uint32_t cc = emu->op1 & (1 << (cnt - 1)); + uint32_t cc = emu->op1.u32 & (1 << (cnt - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); } } - emu->res = d + 1; - emu->op1 = d; + emu->res.u32 = d + 1; + emu->op1.u32 = d; emu->df = d_inc32; - return emu->res; + return emu->res.u32; } static inline uint64_t inc64(x64emu_t *emu, uint64_t d) { if(emu->df == d_shr64) { // workaround for some wine trickery - uint64_t cnt = emu->op2; + uint64_t cnt = emu->op2.u64; if (cnt > 0) { - uint64_t cc = emu->op1 & (1L << (cnt - 1)); + uint64_t cc = emu->op1.u64 & (1LL << (cnt - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); } } - emu->res = d + 1; - emu->op1 = d; + emu->res.u64 = d + 1; + emu->op1.u64 = d; emu->df = d_inc64; - return emu->res; + return emu->res.u64; } static inline uint8_t or8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->res = d | s; + emu->res.u8 = d | s; emu->df = d_or8; - return emu->res; + return emu->res.u8; } static inline uint16_t or16(x64emu_t *emu, uint16_t d, uint16_t s) { - emu->res = d | s; + emu->res.u16 = d | s; emu->df = d_or16; /* set the carry flag to be bit 8 */ - return emu->res; + return emu->res.u16; } static inline uint32_t or32(x64emu_t *emu, uint32_t d, uint32_t s) { - emu->res = d | s; + emu->res.u32 = d | s; emu->df = d_or32; - return emu->res; + return emu->res.u32; } static inline uint64_t or64(x64emu_t *emu, uint64_t d, uint64_t s) { - emu->res = d | s; + emu->res.u64 = d | s; emu->df = d_or64; - return emu->res; + return emu->res.u64; } static inline uint8_t neg8(x64emu_t *emu, uint8_t s) { - emu->res = (uint8_t)-s; - emu->op1 = s; + emu->res.u8 = (uint8_t)-s; + emu->op1.u8 = s; emu->df = d_neg8; - return emu->res; + return emu->res.u8; } static inline uint16_t neg16(x64emu_t *emu, uint16_t s) { - emu->res = (uint16_t)-s; - emu->op1 = s; + emu->res.u16 = (uint16_t)-s; + emu->op1.u16 = s; emu->df = d_neg16; - return emu->res; + return emu->res.u16; } static inline uint32_t neg32(x64emu_t *emu, uint32_t s) { - emu->res = (uint32_t)-s; - emu->op1 = s; + emu->res.u32 = (uint32_t)-s; + emu->op1.u32 = s; emu->df = d_neg32; - return emu->res; + return emu->res.u32; } static inline uint64_t neg64(x64emu_t *emu, uint64_t s) { - emu->res = (uint64_t)-s; - emu->op1 = s; + emu->res.u64 = (uint64_t)-s; + emu->op1.u64 = s; emu->df = d_neg64; - return emu->res; + return emu->res.u64; } static inline uint8_t not8(x64emu_t *emu, uint8_t s) @@ -283,72 +283,72 @@ uint64_t sbb64 (x64emu_t *emu, uint64_t d, uint64_t s); static inline uint8_t shl8(x64emu_t *emu, uint8_t d, uint8_t s) { emu->df = d_shl8; - emu->op1 = d; + emu->op1.u8 = d; s &= 0x1f; - emu->op2 = s; - emu->res = d << s; + emu->op2.u8 = s; + emu->res.u8 = d << s; - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t shl16(x64emu_t *emu, uint16_t d, uint8_t s) { emu->df = d_shl16; - emu->op1 = d; + emu->op1.u16 = d; s &= 0x1f; - emu->op2 = s; - emu->res = d << s; - return (uint16_t)emu->res; + emu->op2.u16 = s; + emu->res.u16 = d << s; + return emu->res.u16; } static inline uint32_t shl32(x64emu_t *emu, uint32_t d, uint8_t s) { emu->df = d_shl32; - emu->op1 = d; + emu->op1.u32 = d; s &= 0x1f; - emu->op2 = s; - emu->res = d << s; + emu->op2.u32 = s; + emu->res.u32 = d << s; - return emu->res; + return emu->res.u32; } static inline uint64_t shl64(x64emu_t *emu, uint64_t d, uint8_t s) { emu->df = d_shl64; - emu->op1 = d; + emu->op1.u64 = d; s &= 0x3f; - emu->op2 = s; - emu->res = d << s; + emu->op2.u64 = s; + emu->res.u64 = d << s; - return emu->res; + return emu->res.u64; } static inline uint8_t shr8(x64emu_t *emu, uint8_t d, uint8_t s) { emu->df = d_shr8; - emu->op1 = d; + emu->op1.u8 = d; s &= 0x1f; - emu->op2 = s; - emu->res = d >> s; + emu->op2.u8 = s; + emu->res.u8 = d >> s; - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t shr16(x64emu_t *emu, uint16_t d, uint8_t s) { emu->df = d_shr16; - emu->op1 = d; + emu->op1.u16 = d; s &= 0x1f; - emu->op2 = s; - emu->res = d >> s; + emu->op2.u16 = s; + emu->res.u16 = d >> s; - return (uint16_t)emu->res; + return emu->res.u16; } static inline uint32_t shr32(x64emu_t *emu, uint32_t d, uint8_t s) @@ -356,13 +356,13 @@ static inline uint32_t shr32(x64emu_t *emu, uint32_t d, uint8_t s) RESET_FLAGS(emu); // TODO: Defered this one? emu->df = d_shr32; - emu->op1 = d; + emu->op1.u32 = d; s &= 0x1f; - emu->op2 = s; - emu->res = d >> s; + emu->op2.u32 = s; + emu->res.u32 = d >> s; - return emu->res; + return emu->res.u32; } static inline uint64_t shr64(x64emu_t *emu, uint64_t d, uint8_t s) @@ -370,97 +370,97 @@ static inline uint64_t shr64(x64emu_t *emu, uint64_t d, uint8_t s) RESET_FLAGS(emu); // TODO: Defered this one? emu->df = d_shr64; - emu->op1 = d; + emu->op1.u64 = d; s &= 0x3f; - emu->op2 = s; - emu->res = d >> s; + emu->op2.u64 = s; + emu->res.u64 = d >> s; - return emu->res; + return emu->res.u64; } static inline uint8_t sar8(x64emu_t *emu, uint8_t d, uint8_t s) { emu->df = d_sar8; - emu->op1 = d; + emu->op1.u8 = d; s &= 0x1f; - emu->op2 = s; - emu->res = (uint8_t)(((int8_t)d)>>s); + emu->op2.u8 = s; + emu->res.u8 = (uint8_t)(((int8_t)d)>>s); - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t sar16(x64emu_t *emu, uint16_t d, uint8_t s) { emu->df = d_sar16; - emu->op1 = d; + emu->op1.u16 = d; s &= 0x1f; - emu->op2 = s; - emu->res = (uint16_t)(((int16_t)d)>>s); + emu->op2.u16 = s; + emu->res.u16 = (uint16_t)(((int16_t)d)>>s); - return (uint16_t)emu->res; + return emu->res.u16; } static inline uint32_t sar32(x64emu_t *emu, uint32_t d, uint8_t s) { emu->df = d_sar32; - emu->op1 = d; + emu->op1.u32 = d; s &= 0x1f; - emu->op2 = s; - emu->res = (uint32_t)(((int32_t)d)>>s); + emu->op2.u32 = s; + emu->res.u32 = (uint32_t)(((int32_t)d)>>s); - return emu->res; + return emu->res.u32; } static inline uint64_t sar64(x64emu_t *emu, uint64_t d, uint8_t s) { emu->df = d_sar64; - emu->op1 = d; + emu->op1.u64 = d; s &= 0x3f; - emu->op2 = s; - emu->res = (uint64_t)(((int64_t)d)>>s); + emu->op2.u64 = s; + emu->res.u64 = (uint64_t)(((int64_t)d)>>s); - return emu->res; + return emu->res.u64; } static inline uint8_t sub8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->res = d - s; - emu->op1 = d; - emu->op2 = s; + emu->res.u8 = d - s; + emu->op1.u8 = d; + emu->op2.u8 = s; emu->df = d_sub8; - return (uint8_t)emu->res; + return emu->res.u8; } static inline uint16_t sub16(x64emu_t *emu, uint16_t d, uint16_t s) { - emu->res = d - s; - emu->op1 = d; - emu->op2 = s; + emu->res.u16 = d - s; + emu->op1.u16 = d; + emu->op2.u16 = s; emu->df = d_sub16; - return (uint16_t)emu->res; + return emu->res.u16; } static inline uint32_t sub32(x64emu_t *emu, uint32_t d, uint32_t s) { - emu->res = d - s; - emu->op1 = d; - emu->op2 = s; + emu->res.u32 = d - s; + emu->op1.u32 = d; + emu->op2.u32 = s; emu->df = d_sub32; - return emu->res; + return emu->res.u32; } static inline uint64_t sub64(x64emu_t *emu, uint64_t d, uint64_t s) { - emu->res = d - s; - emu->op1 = d; - emu->op2 = s; + emu->res.u64 = d - s; + emu->op1.u64 = d; + emu->op2.u64 = s; emu->df = d_sub64; - return emu->res; + return emu->res.u64; } void test8 (x64emu_t *emu, uint8_t d, uint8_t s); @@ -470,52 +470,52 @@ void test64 (x64emu_t *emu, uint64_t d, uint64_t s); static inline uint8_t xor8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->res = d ^ s; + emu->res.u8 = d ^ s; emu->df = d_xor8; - return emu->res; + return emu->res.u8; } static inline uint16_t xor16(x64emu_t *emu, uint16_t d, uint16_t s) { - emu->res = d ^ s; + emu->res.u16 = d ^ s; emu->df = d_xor16; - return emu->res; + return emu->res.u16; } static inline uint32_t xor32(x64emu_t *emu, uint32_t d, uint32_t s) { - emu->res = d ^ s; + emu->res.u32 = d ^ s; emu->df = d_xor32; - return emu->res; + return emu->res.u32; } static inline uint64_t xor64(x64emu_t *emu, uint64_t d, uint64_t s) { - emu->res = d ^ s; + emu->res.u64 = d ^ s; emu->df = d_xor64; - return emu->res; + return emu->res.u64; } static inline void imul8(x64emu_t *emu, uint8_t s) { emu->df = d_imul8; - R_AX = emu->res = (int16_t)(int8_t)R_AL * (int8_t)s; + R_AX = emu->res.u16 = (int16_t)(int8_t)R_AL * (int8_t)s; } static inline void imul16_eax(x64emu_t *emu, uint16_t s) { emu->df = d_imul16; - emu->res = (int32_t)(int16_t)R_AX * (int16_t)s; - R_AX = (uint16_t)emu->res; - R_DX = (uint16_t)(emu->res >> 16); + emu->res.u32 = (int32_t)(int16_t)R_AX * (int16_t)s; + R_AX = (uint16_t)emu->res.u32; + R_DX = (uint16_t)(emu->res.u32 >> 16); } static inline uint16_t imul16(x64emu_t *emu, uint16_t op1, uint16_t op2) { emu->df = d_imul16; - emu->res = (int32_t)(int16_t)op1 * (int16_t)op2; - return (uint16_t)emu->res; + emu->res.u32 = (int32_t)(int16_t)op1 * (int16_t)op2; + return emu->res.u16; } static inline void imul32_direct(uint32_t *res_lo, uint32_t* res_hi,uint32_t d, uint32_t s) @@ -531,17 +531,17 @@ static inline uint32_t imul32(x64emu_t *emu, uint32_t op1, uint32_t op2) emu->df = d_imul32; uint32_t _res, _op1; imul32_direct(&_res,&_op1,op1,op2); - emu->res = _res; - emu->op1 = _op1; - return emu->res; + emu->res.u32 = _res; + emu->op1.u32 = _op1; + return emu->res.u32; } static inline void imul32_eax(x64emu_t *emu, uint32_t s) { emu->df = d_imul32; imul32_direct(&R_EAX,&R_EDX,R_EAX,s); - emu->res = R_EAX; - emu->op1 = R_EDX; + emu->res.u32 = R_EAX; + emu->op1.u32 = R_EDX; } static inline void imul64_direct(uint64_t *res_lo, uint64_t* res_hi,uint64_t d, uint64_t s) @@ -555,46 +555,46 @@ static inline void imul64_direct(uint64_t *res_lo, uint64_t* res_hi,uint64_t d, static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2) { emu->df = d_imul64; - imul64_direct(&emu->res,&emu->op1,op1,op2); - return emu->res; + imul64_direct(&emu->res.u64,&emu->op1.u64,op1,op2); + return emu->res.u64; } static inline void imul64_rax(x64emu_t *emu, uint64_t s) { emu->df = d_imul64; imul64_direct(&R_RAX,&R_RDX,R_RAX,s); - emu->res = R_RAX; - emu->op1 = R_RDX; + emu->res.u64 = R_RAX; + emu->op1.u64 = R_RDX; } static inline void mul8(x64emu_t *emu, uint8_t s) { emu->df = d_mul8; - R_AX = emu->res = (uint16_t)(R_AL) * s; + R_AX = emu->res.u16 = (uint16_t)(R_AL) * s; } static inline void mul16(x64emu_t *emu, uint16_t s) { emu->df = d_mul16; - emu->res = (uint32_t)R_AX * s; - R_AX = (uint16_t)emu->res; - R_DX = (uint16_t)(emu->res >> 16); + emu->res.u32 = (uint32_t)R_AX * s; + R_AX = (uint16_t)emu->res.u32; + R_DX = (uint16_t)(emu->res.u32 >> 16); } static inline void mul32_eax(x64emu_t *emu, uint32_t s) { emu->df = d_mul32; uint64_t res = (uint64_t)R_EAX * s; - emu->res = R_EAX = (uint32_t)res; - emu->op1 = R_EDX = (uint32_t)(res >> 32); + emu->res.u32 = R_EAX = (uint32_t)res; + emu->op1.u32 = R_EDX = (uint32_t)(res >> 32); } static inline void mul64_rax(x64emu_t *emu, uint64_t s) { emu->df = d_mul64; __int128 res = (__int128)R_RAX * s; - emu->res = R_RAX = (uint64_t)res; - emu->op1 = R_RDX = (uint64_t)(res >> 64); + emu->res.u64 = R_RAX = (uint64_t)res; + emu->op1.u64 = R_RDX = (uint64_t)(res >> 64); } void idiv8 (x64emu_t *emu, uint8_t s); diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index cfb4d440..b279ca1d 100755 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -96,41 +96,52 @@ void UpdateFlags(x64emu_t *emu) case d_none: return; case d_add8: - CONDITIONAL_SET_FLAG(emu->res & 0x100, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x100, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_add16: - CONDITIONAL_SET_FLAG(emu->res & 0x10000, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_add32: - CONDITIONAL_SET_FLAG(emu->res & 0x100000000LL, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x100000000LL, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u64 & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add32b: + lo = (emu->op2.u32 & 0xFFFF) + (emu->op1.u32 & 0xFFFF); + hi = (lo >> 16) + (emu->op2.u32 >> 16) + (emu->op1.u32 >> 16); + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_add64: - lo = (emu->op2 & 0xFFFFFFFF) + (emu->op1 & 0xFFFFFFFF); - hi = (lo >> 32) + (emu->op2 >> 32) + (emu->op1 >> 32); + lo = (emu->op2.u64 & 0xFFFFFFFF) + (emu->op1.u64 & 0xFFFFFFFF); + hi = (lo >> 32) + (emu->op2.u64 >> 32) + (emu->op1.u64 >> 32); CONDITIONAL_SET_FLAG(hi & 0x100000000, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + cc = (emu->op1.u64 & emu->op2.u64) | ((~emu->res.u64) & (emu->op1.u64 | emu->op2.u64)); CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; @@ -138,101 +149,101 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u8 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); break; case d_and16: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u16 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); break; case d_and32: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u32 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); break; case d_and64: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); break; case d_dec8: - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | 1)) | (~emu->op1 & 1); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | 1)) | (~emu->op1.u8 & 1); CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_dec16: - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | 1)) | (~emu->op1 & 1); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u16) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | 1)) | (~emu->op1.u16 & 1); CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_dec32: - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | 1)) | (~emu->op1 & 1); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | 1)) | (~emu->op1.u32 & 1); CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_dec64: - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | 1)) | (~emu->op1 & 1); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | 1)) | (~emu->op1.u64 & 1); CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_inc8: - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = ((1 & emu->op1) | (~emu->res)) & (1 | emu->op1); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + cc = ((1 & emu->op1.u8) | (~emu->res.u8)) & (1 | emu->op1.u8); CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_inc16: - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (1 & emu->op1) | ((~emu->res) & (1 | emu->op1)); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + cc = (1 & emu->op1.u16) | ((~emu->res.u16) & (1 | emu->op1.u16)); CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_inc32: - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (1 & emu->op1) | ((~emu->res) & (1 | emu->op1)); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + cc = (1 & emu->op1.u32) | ((~emu->res.u32) & (1 | emu->op1.u32)); CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_inc64: - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (1 & emu->op1) | ((~emu->res) & (1 | emu->op1)); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + cc = (1 & emu->op1.u64) | ((~emu->res.u64) & (1 | emu->op1.u64)); CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_imul8: - lo = emu->res & 0xff; - hi = (emu->res>>8)&0xff; + lo = emu->res.u16 & 0xff; + hi = (emu->res.u16>>8)&0xff; if (((lo & 0x80) == 0 && hi == 0x00) || ((lo & 0x80) != 0 && hi == 0xFF)) { CLEAR_FLAG(F_CF); @@ -244,8 +255,8 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); break; case d_imul16: - lo = (uint16_t)emu->res; - hi = (uint16_t)(emu->res >> 16); + lo = (uint16_t)emu->res.u32; + hi = (uint16_t)(emu->res.u32 >> 16); if (((lo & 0x8000) == 0 && hi == 0x00) || ((lo & 0x8000) != 0 && hi == 0xFFFF)) { CLEAR_FLAG(F_CF); @@ -257,30 +268,30 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); break; case d_imul32: - if (((emu->res & 0x80000000) == 0 && emu->op1 == 0x00) || - ((emu->res & 0x80000000) != 0 && emu->op1 == 0xFFFFFFFF)) { + if (((emu->res.u32 & 0x80000000) == 0 && emu->op1.u32 == 0x00) || + ((emu->res.u32 & 0x80000000) != 0 && emu->op1.u32 == 0xFFFFFFFF)) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); break; case d_imul64: - if (((emu->res & 0x8000000000000000LL) == 0 && emu->op1 == 0x00) || - ((emu->res & 0x8000000000000000LL) != 0 && emu->op1 == 0xFFFFFFFFFFFFFFFFLL)) { + if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) || + ((emu->res.u64 & 0x8000000000000000LL) != 0 && emu->op1.u64 == 0xFFFFFFFFFFFFFFFFLL)) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); break; case d_mul8: - lo = emu->res & 0xff; - hi = (emu->res>>8)&0xff; + lo = emu->res.u16 & 0xff; + hi = (emu->res.u16>>8)&0xff; if (hi == 0) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); @@ -291,8 +302,8 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); break; case d_mul16: - lo = (uint16_t)emu->res; - hi = (uint16_t)(emu->res >> 16); + lo = (uint16_t)emu->res.u32; + hi = (uint16_t)(emu->res.u32 >> 16); if (hi == 0) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); @@ -303,110 +314,110 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); break; case d_mul32: - if (emu->op1 == 0) { + if (emu->op1.u32 == 0) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); break; case d_mul64: - if (emu->op1 == 0) { + if (emu->op1.u64 == 0) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); break; case d_or8: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u8 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); break; case d_or16: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u16 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); break; case d_or32: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u32 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); break; case d_or64: CLEAR_FLAG(F_OF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); break; case d_neg8: - CONDITIONAL_SET_FLAG(emu->op1 != 0, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = emu->res | emu->op1; + CONDITIONAL_SET_FLAG(emu->op1.u8 != 0, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + bc = emu->res.u8 | emu->op1.u8; CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_neg16: - CONDITIONAL_SET_FLAG(emu->op1 != 0, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = emu->res | emu->op1; + CONDITIONAL_SET_FLAG(emu->op1.u16 != 0, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + bc = emu->res.u16 | emu->op1.u16; CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_neg32: - CONDITIONAL_SET_FLAG(emu->op1 != 0, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = emu->res | emu->op1; + CONDITIONAL_SET_FLAG(emu->op1.u32 != 0, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + bc = emu->res.u32 | emu->op1.u32; CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_neg64: - CONDITIONAL_SET_FLAG(emu->op1 != 0, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = emu->res | emu->op1; + CONDITIONAL_SET_FLAG(emu->op1.u64 != 0, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + bc = emu->res.u64 | emu->op1.u64; CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_shl8: - if (emu->op2 < 8) { - cnt = emu->op2 % 8; + if (emu->op2.u8 < 8) { + cnt = emu->op2.u8 % 8; if (cnt > 0) { - cc = emu->op1 & (1 << (8 - cnt)); + cc = emu->op1.u8 & (1 << (8 - cnt)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG((((emu->res & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); + CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { - CONDITIONAL_SET_FLAG((emu->op1 << (emu->op2-1)) & 0x80, F_CF); + CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); @@ -414,22 +425,22 @@ void UpdateFlags(x64emu_t *emu) } break; case d_shl16: - if (emu->op2 < 16) { - cnt = emu->op2 % 16; + if (emu->op2.u16 < 16) { + cnt = emu->op2.u16 % 16; if (cnt > 0) { - cc = emu->op1 & (1 << (16 - cnt)); + cc = emu->op1.u16 & (1 << (16 - cnt)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(((!!(emu->res & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); + CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { - CONDITIONAL_SET_FLAG((emu->op1 << (emu->op2-1)) & 0x8000, F_CF); + CONDITIONAL_SET_FLAG((emu->op1.u16 << (emu->op2.u16-1)) & 0x8000, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); @@ -437,23 +448,23 @@ void UpdateFlags(x64emu_t *emu) } break; case d_shl32: - if (emu->op2 < 32) { - cnt = emu->op2 % 32; + if (emu->op2.u32 < 32) { + cnt = emu->op2.u32 % 32; if (cnt > 0) { - cc = emu->op1 & (1 << (32 - cnt)); + cc = emu->op1.u32 & (1 << (32 - cnt)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(((!!(emu->res & 0x80000000)) ^ + CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^ (ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { - CONDITIONAL_SET_FLAG((emu->op1 << (emu->op2-1)) & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG((emu->op1.u32 << (emu->op2.u32-1)) & 0x80000000, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); @@ -461,31 +472,31 @@ void UpdateFlags(x64emu_t *emu) } break; case d_shl64: - if (emu->op2 > 0) { - cc = emu->op1 & (1LL << (64 - emu->op2)); + if (emu->op2.u64 > 0) { + cc = emu->op1.u64 & (1LL << (64 - emu->op2.u64)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); } - if (emu->op2 == 1) { - CONDITIONAL_SET_FLAG(((!!(emu->res & 0x8000000000000000LL)) ^ + if (emu->op2.u64 == 1) { + CONDITIONAL_SET_FLAG(((!!(emu->res.u64 & 0x8000000000000000LL)) ^ (ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } break; case d_sar8: - if (emu->op2 < 8) { - if(emu->op2) { - cc = emu->op1 & (1 << (emu->op2 - 1)); + if (emu->op2.u8 < 8) { + if(emu->op2.u8) { + cc = emu->op1.u8 & (1 << (emu->op2.u8 - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); } } else { - if (emu->op1&0x80) { + if (emu->op1.u8&0x80) { SET_FLAG(F_CF); CLEAR_FLAG(F_ZF); SET_FLAG(F_SF); @@ -499,16 +510,16 @@ void UpdateFlags(x64emu_t *emu) } break; case d_sar16: - if (emu->op2 < 16) { - if(emu->op2) { - cc = emu->op1 & (1 << (emu->op2 - 1)); + if (emu->op2.u16 < 16) { + if(emu->op2.u16) { + cc = emu->op1.u16 & (1 << (emu->op2.u16 - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); } } else { - if (emu->op1&0x8000) { + if (emu->op1.u16&0x8000) { SET_FLAG(F_CF); CLEAR_FLAG(F_ZF); SET_FLAG(F_SF); @@ -522,16 +533,16 @@ void UpdateFlags(x64emu_t *emu) } break; case d_sar32: - if (emu->op2 < 32) { - if(emu->op2) { - cc = emu->op1 & (1 << (emu->op2 - 1)); + if (emu->op2.u32 < 32) { + if(emu->op2.u32) { + cc = emu->op1.u32 & (1 << (emu->op2.u32 - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); } } else { - if (emu->op1&0x80000000) { + if (emu->op1.u32&0x80000000) { SET_FLAG(F_CF); CLEAR_FLAG(F_ZF); SET_FLAG(F_SF); @@ -545,46 +556,46 @@ void UpdateFlags(x64emu_t *emu) } break; case d_sar64: - if(emu->op2) { - cc = emu->op1 & (1LL << (emu->op2 - 1)); + if(emu->op2.u64) { + cc = emu->op1.u64 & (1LL << (emu->op2.u64 - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); } break; case d_shr8: - if (emu->op2 < 8) { - cnt = emu->op2 % 8; + if (emu->op2.u8 < 8) { + cnt = emu->op2.u8 % 8; if (cnt > 0) { - cc = emu->op1 & (1 << (cnt - 1)); + cc = emu->op1.u8 & (1 << (cnt - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 6), F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF); } } else { - CONDITIONAL_SET_FLAG((emu->op1 >> (emu->op2-1)) & 0x1, F_CF); + CONDITIONAL_SET_FLAG((emu->op1.u8 >> (emu->op2.u8-1)) & 0x1, F_CF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); } break; case d_shr16: - if (emu->op2 < 16) { - cnt = emu->op2 % 16; + if (emu->op2.u16 < 16) { + cnt = emu->op2.u16 % 16; if (cnt > 0) { - cc = emu->op1 & (1 << (cnt - 1)); + cc = emu->op1.u16 & (1 << (cnt - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 14), F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); } } else { CLEAR_FLAG(F_CF); @@ -594,17 +605,17 @@ void UpdateFlags(x64emu_t *emu) } break; case d_shr32: - if (emu->op2 < 32) { - cnt = emu->op2 % 32; + if (emu->op2.u32 < 32) { + cnt = emu->op2.u32 % 32; if (cnt > 0) { - cc = emu->op1 & (1 << (cnt - 1)); + cc = emu->op1.u32 & (1 << (cnt - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 30), F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); } } else { CLEAR_FLAG(F_CF); @@ -614,276 +625,276 @@ void UpdateFlags(x64emu_t *emu) } break; case d_shr64: - cnt = emu->op2; + cnt = emu->op2.u64; if (cnt > 0) { - cc = emu->op1 & (1LL << (cnt - 1)); + cc = emu->op1.u64 & (1LL << (cnt - 1)); CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 62), F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); } break; case d_sub8: - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_sub16: - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_sub32: - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_sub64: - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_xor8: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u8 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); break; case d_xor16: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u16 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); break; case d_xor32: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u32 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); break; case d_xor64: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); CLEAR_FLAG(F_CF); CLEAR_FLAG(F_AF); break; case d_cmp8: CLEAR_FLAG(F_CF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_cmp16: - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_cmp32: - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_cmp64: - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_tst8: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u8 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); CLEAR_FLAG(F_CF); break; case d_tst16: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u16 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); CLEAR_FLAG(F_CF); break; case d_tst32: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u32 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); CLEAR_FLAG(F_CF); break; case d_tst64: CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(emu->res == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); CLEAR_FLAG(F_CF); break; case d_adc8: - CONDITIONAL_SET_FLAG(emu->res & 0x100, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x100, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_adc16: - CONDITIONAL_SET_FLAG(emu->res & 0x10000, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_adc32: - CONDITIONAL_SET_FLAG(emu->res & 0x100000000L, F_CF); - CONDITIONAL_SET_FLAG((emu->res & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op1 & emu->op2) | ((~emu->res) & (emu->op1 | emu->op2)); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x100000000L, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_adc64: - if(emu->res == (emu->op1+emu->op2)) { - lo = (emu->op1 & 0xFFFFFFFF) + (emu->op2 & 0xFFFFFFFF); + if(emu->res.u64 == (emu->op1.u64+emu->op2.u64)) { + lo = (emu->op1.u64 & 0xFFFFFFFF) + (emu->op2.u64 & 0xFFFFFFFF); } else { - lo = 1 + (emu->op1 & 0xFFFFFFFF) + (emu->op2 & 0xFFFFFFFF); + lo = 1 + (emu->op1.u64 & 0xFFFFFFFF) + (emu->op2.u64 & 0xFFFFFFFF); } - hi = (lo >> 32) + (emu->op1 >> 32) + (emu->op2 >> 32); + hi = (lo >> 32) + (emu->op1.u64 >> 32) + (emu->op2.u64 >> 32); CONDITIONAL_SET_FLAG(hi & 0x1000000000000L, F_CF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - cc = (emu->op2 & emu->op1) | ((~emu->res) & (emu->op2 | emu->op1)); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + cc = (emu->op2.u64 & emu->op1.u64) | ((~emu->res.u64) & (emu->op2.u64 | emu->op1.u64)); CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); break; case d_sbb8: - CONDITIONAL_SET_FLAG(emu->res & 0x80, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_sbb16: - CONDITIONAL_SET_FLAG(emu->res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((emu->res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_sbb32: - CONDITIONAL_SET_FLAG(emu->res & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_sbb64: - CONDITIONAL_SET_FLAG(emu->res & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res & 0xff), F_PF); - bc = (emu->res & (~emu->op1 | emu->op2)) | (~emu->op1 & emu->op2); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_rol8: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG((emu->res + (emu->res >> 7)) & 1, F_OF); + if(emu->op2.u8 == 1) { + CONDITIONAL_SET_FLAG((emu->res.u8 + (emu->res.u8 >> 7)) & 1, F_OF); } - CONDITIONAL_SET_FLAG(emu->res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x1, F_CF); break; case d_rol16: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG((emu->res + (emu->res >> 15)) & 1, F_OF); + if(emu->op2.u16 == 1) { + CONDITIONAL_SET_FLAG((emu->res.u16 + (emu->res.u16 >> 15)) & 1, F_OF); } - CONDITIONAL_SET_FLAG(emu->res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x1, F_CF); break; case d_rol32: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG((emu->res + (emu->res >> 31)) & 1, F_OF); + if(emu->op2.u32 == 1) { + CONDITIONAL_SET_FLAG((emu->res.u32 + (emu->res.u32 >> 31)) & 1, F_OF); } - CONDITIONAL_SET_FLAG(emu->res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x1, F_CF); break; case d_rol64: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG((emu->res + (emu->res >> 63)) & 1, F_OF); + if(emu->op2.u64 == 1) { + CONDITIONAL_SET_FLAG((emu->res.u64 + (emu->res.u64 >> 63)) & 1, F_OF); } - CONDITIONAL_SET_FLAG(emu->res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x1, F_CF); break; case d_ror8: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 6), F_OF); + if(emu->op2.u8 == 1) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF); } - CONDITIONAL_SET_FLAG(emu->res & (1 << 7), F_CF); + CONDITIONAL_SET_FLAG(emu->res.u8 & (1 << 7), F_CF); break; case d_ror16: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 14), F_OF); + if(emu->op2.u16 == 1) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); } - CONDITIONAL_SET_FLAG(emu->res & (1 << 15), F_CF); + CONDITIONAL_SET_FLAG(emu->res.u16 & (1 << 15), F_CF); break; case d_ror32: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 30), F_OF); + if(emu->op2.u32 == 1) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); } - CONDITIONAL_SET_FLAG(emu->res & (1 << 31), F_CF); + CONDITIONAL_SET_FLAG(emu->res.u32 & (1 << 31), F_CF); break; case d_ror64: - if(emu->op2 == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res >> 62), F_OF); + if(emu->op2.u64 == 1) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); } - CONDITIONAL_SET_FLAG(emu->res & (1L << 63), F_CF); + CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF); break; case d_rcl8: diff --git a/src/include/regs.h b/src/include/regs.h index 3e9efb0a..008b61bc 100755 --- a/src/include/regs.h +++ b/src/include/regs.h @@ -47,7 +47,8 @@ typedef enum { d_none = 0, d_add8, d_add16, - d_add32, + d_add32, // using 64bits res + d_add32b, // using 32bits res d_add64, d_and8, d_and16, |