about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-17 11:17:49 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-17 11:17:49 +0100
commite8d2b6d25d3718355bc2cd5c30fcab74e81eeb8b (patch)
treebae54424b4ff21e9f935dcd1ce668495fe571a3b /src
parentd1a037b38b647ac54c11a1b1e00a800205193ada (diff)
downloadbox64-e8d2b6d25d3718355bc2cd5c30fcab74e81eeb8b.tar.gz
box64-e8d2b6d25d3718355bc2cd5c30fcab74e81eeb8b.zip
Excplicit handling of bit size for defered flags
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_emit_math.c17
-rwxr-xr-xsrc/dynarec/dynarec_arm64_emit_tests.c2
-rwxr-xr-xsrc/emu/x64emu_private.h13
-rwxr-xr-xsrc/emu/x64primop.h334
-rwxr-xr-xsrc/emu/x64run_private.c649
-rwxr-xr-xsrc/include/regs.h3
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,