about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-06-05 08:58:51 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-06-05 10:23:38 +0200
commit42670c0130172da006357ba0f455a2a209bdebf8 (patch)
tree111b87553a9f4648e47115ef8142c6721ca61b1a /src
parentf4c15979db68706b96380b2e827210b3d178a702 (diff)
downloadbox64-42670c0130172da006357ba0f455a2a209bdebf8.tar.gz
box64-42670c0130172da006357ba0f455a2a209bdebf8.zip
Fixed BT/BTC/BTR/BTS opcodes ([DYNAREC] too)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c48
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c69
-rw-r--r--src/emu/x64run0f.c43
-rw-r--r--src/emu/x64run660f.c66
4 files changed, 148 insertions, 78 deletions
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index 2660fbbf..37107026 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -969,19 +969,18 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0xA3:

             INST_NAME("BT Ed, Gd");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             GETGD;

             if(MODREG) {

                 ed = xRAX+(nextop&7)+(rex.b<<3);

-                wback = 0;

             } else {

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);

-                UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5);

-                ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4;

+                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDRxw_U12(x1, x3, fixedaddress);

                 ed = x1;

-                wback = x3;

             }

             if(rex.w) {

                 ANDx_mask(x2, gd, 1, 0, 0b00101);  //mask=0x000000000000003f

@@ -1006,7 +1005,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 

         case 0xAB:

             INST_NAME("BTS Ed, Gd");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             GETGD;

             if(MODREG) {

@@ -1014,8 +1014,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 wback = 0;

             } else {

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);

-                UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5);

-                ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4;

+                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDRxw_U12(x1, x3, fixedaddress);

                 ed = x1;

                 wback = x3;

@@ -1142,7 +1142,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 

         case 0xB3:

             INST_NAME("BTR Ed, Gd");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             GETGD;

             if(MODREG) {

@@ -1150,8 +1151,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 wback = 0;

             } else {

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);

-                UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5);

-                ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4;

+                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDRxw_U12(x1, x3, fixedaddress);

                 ed = x1;

                 wback = x3;

@@ -1215,17 +1216,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:

                     INST_NAME("BT Ed, Ib");

                     SETFLAGS(X_CF, SF_SUBSET);

+                    SET_DFNONE(x1);

                     gd = x2;

                     if(MODREG) {

                         ed = xRAX+(nextop&7)+(rex.b<<3);

-                        u8 = F8;

                     } else {

                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1);

-                        u8 = F8;

-                        fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4);

                         LDRxw_U12(x1, wback, fixedaddress);

                         ed = x1;

                     }

+                    u8 = F8;

                     u8&=rex.w?0x3f:0x1f;

                     if(u8) {

                         LSRxw(x1, ed, u8);

@@ -1236,17 +1236,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 5:

                     INST_NAME("BTS Ed, Ib");

                     SETFLAGS(X_CF, SF_SUBSET);

+                    SET_DFNONE(x1);

                     if(MODREG) {

                         ed = xRAX+(nextop&7)+(rex.b<<3);

-                        u8 = F8;

                         wback = 0;

                     } else {

                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1);

-                        u8 = F8;

-                        fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4);

                         LDRxw_U12(x1, wback, fixedaddress);

                         ed = x1;

                     }

+                    u8 = F8;

                     LSRxw(x4, ed, u8&(rex.w?0x3f:0x1f));

                     BFIw(xFlags, x4, F_CF, 1);

                     TBNZ_MARK3(x4, 0); // bit already set, jump to next instruction

@@ -1260,17 +1259,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:

                     INST_NAME("BTR Ed, Ib");

                     SETFLAGS(X_CF, SF_SUBSET);

+                    SET_DFNONE(x1);

                     if(MODREG) {

                         ed = xRAX+(nextop&7)+(rex.b<<3);

-                        u8 = F8;

                         wback = 0;

                     } else {

                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1);

-                        u8 = F8;

-                        fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4);

                         LDRxw_U12(x1, wback, fixedaddress);

                         ed = x1;

                     }

+                    u8 = F8;

                     LSRxw(x4, ed, u8&(rex.w?0x3f:0x1f));

                     BFIw(xFlags, x4, F_CF, 1);

                     TBZ_MARK3(x4, 0); // bit already clear, jump to next instruction

@@ -1284,17 +1282,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 7:

                     INST_NAME("BTC Ed, Ib");

                     SETFLAGS(X_CF, SF_SUBSET);

+                    SET_DFNONE(x1);

                     if(MODREG) {

                         ed = xRAX+(nextop&7)+(rex.b<<3);

-                        u8 = F8;

                         wback = 0;

                     } else {

                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1);

-                        u8 = F8;

-                        fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4);

                         LDRxw_U12(x1, wback, fixedaddress);

                         ed = x1;

                     }

+                    u8 = F8;

                     LSRxw(x4, ed, u8&(rex.w?0x3f:0x1f));

                     BFIw(xFlags, x4, F_CF, 1);

                     MOV32w(x4, 1);

@@ -1311,6 +1308,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xBB:

             INST_NAME("BTC Ed, Gd");

             SETFLAGS(X_CF, SF_SET);

+            SET_DFNONE(x1);

             nextop = F8;

             GETGD;

             if(MODREG) {

@@ -1318,8 +1316,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 wback = 0;

             } else {

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);

-                UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5);

-                ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4;

+                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDRxw_U12(x1, x3, fixedaddress);

                 ed = x1;

                 wback = x3;

diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index 999dc6e5..3cb870bf 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -850,10 +850,19 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

         case 0xA3:

             INST_NAME("BT Ew, Gw");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);    // GETGD

-            GETEW(x4, 0);

+            if(MODREG) {

+                ed = xRAX+(nextop&7)+(rex.b<<3);

+            } else {

+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0);

+                SBFXw(x1, gd, 4, 12);   // r1 = (gw>>4)

+                ADDx_REG_LSL(x3, wback, x1, 1); //(&ed)+=r1*2;

+                LDRH_U12(x1, x3, fixedaddress);

+                ed = x1;

+            }

             ANDw_mask(x2, gd, 0, 0b000011);  // mask=0x0f

             LSRw_REG(x1, ed, x2);

             BFIw(xFlags, x1, F_CF, 1);

@@ -880,10 +889,20 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

         case 0xAB:

             INST_NAME("BTS Ew, Gw");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);    // GETGD

-            GETEW(x4, 0);

+            if(MODREG) {

+                ed = xRAX+(nextop&7)+(rex.b<<3);

+                wback = 0;

+            } else {

+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0);

+                SBFXw(x4, gd, 4, 12);   // r1 = (gw>>4)

+                ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;

+                LDRH_U12(x4, x3, fixedaddress);

+                ed = x4;

+            }

             ANDw_mask(x2, gd, 0, 0b000011);  // mask=0x0f

             LSRw_REG(x1, ed, x2);

             BFIw(xFlags, x1, F_CF, 1);

@@ -892,7 +911,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

             EORxw_REG(ed, ed, x1);

-            EWBACK;

+            if(wback) {

+                STRH_U12(ed, wback, fixedaddress);

+            }

             break;

         case 0xAC:

         case 0xAD:

@@ -928,10 +949,21 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

         case 0xB3:

             INST_NAME("BTR Ew, Gw");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);    // GETGD

-            GETEW(x4, 0);

+            if(MODREG) {

+                ed = xRAX+(nextop&7)+(rex.b<<3);

+                wback = 0;

+            } else {

+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0);

+                SBFXw(x4, gd, 4, 12);   // r1 = (gw>>4)

+                ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;

+                LDRH_U12(x4, x3, fixedaddress);

+                wback = x3;

+                ed = x4;

+            }

             ANDw_mask(x2, gd, 0, 0b000011);  // mask=0x0f

             LSRw_REG(x1, ed, x2);

             BFIw(xFlags, x1, F_CF, 1);

@@ -940,7 +972,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

             EORxw_REG(ed, ed, x1);

-            EWBACK;

+            if(wback) {

+                STRH_U12(ed, wback, fixedaddress);

+            }

             break;

 

         case 0xB6:

@@ -966,10 +1000,21 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

         case 0xBB:

             INST_NAME("BTC Ew, Gw");

-            SETFLAGS(X_CF, SF_SET);

+            SETFLAGS(X_CF, SF_SUBSET);

+            SET_DFNONE(x1);

             nextop = F8;

             gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);    // GETGD

-            GETEW(x4, 0);

+            if(MODREG) {

+                ed = xRAX+(nextop&7)+(rex.b<<3);

+                wback = 0;

+            } else {

+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0);

+                SBFXw(x4, gd, 4, 12);   // r1 = (gw>>4)

+                ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;

+                LDRH_U12(x4, x3, fixedaddress);

+                wback = x3;

+                ed = x4;

+            }

             ANDw_mask(x2, gd, 0, 0b000011);  // mask=0x0f

             LSRw_REG(x1, ed, x2);

             BFIw(xFlags, x1, F_CF, 1);

@@ -977,7 +1022,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

             EORxw_REG(ed, ed, x1);

-            EWBACK;

+            if(wback) {

+                STRH_U12(ed, wback, fixedaddress);

+            }

             break;

         case 0xBC:

             INST_NAME("BSF Ew,Gw");

diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 887ca31c..30c89c0b 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -712,19 +712,19 @@ int Run0F(x64emu_t *emu, rex_t rex)
             nextop = F8;

             GETED(0);

             GETGD;

-            tmp8u = GD->byte[0];

+            tmp32s = GD->sdword[0];

+            tmp8u=tmp32s&(rex.w?63:31);

+            tmp32s >>= (rex.w?6:5);

             if(!MODREG)

             {

-                ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5));

+                ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2)));

             }

             if(rex.w) {

-                tmp8u&=63;

                 if(ED->q[0] & (1LL<<tmp8u))

                     SET_FLAG(F_CF);

                 else

                     CLEAR_FLAG(F_CF);

             } else {

-                tmp8u&=31;

                 if(ED->dword[0] & (1<<tmp8u))

                     SET_FLAG(F_CF);

                 else

@@ -755,13 +755,14 @@ int Run0F(x64emu_t *emu, rex_t rex)
             nextop = F8;

             GETED(0);

             GETGD;

-            tmp8u = GD->byte[0];

+            tmp32s = GD->sdword[0];

+            tmp8u=tmp32s&(rex.w?63:31);

+            tmp32s >>= (rex.w?6:5);

             if(!MODREG)

             {

-                ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5));

+                ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2)));

             }

             if(rex.w) {

-                tmp8u&=63;

                 if(ED->q[0] & (1LL<<tmp8u))

                     SET_FLAG(F_CF);

                 else {

@@ -769,7 +770,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     CLEAR_FLAG(F_CF);

                 }

             } else {

-                tmp8u&=31;

                 if(ED->dword[0] & (1<<tmp8u))

                     SET_FLAG(F_CF);

                 else {

@@ -882,20 +882,20 @@ int Run0F(x64emu_t *emu, rex_t rex)
             nextop = F8;

             GETED(0);

             GETGD;

-            tmp8u = GD->byte[0];

+            tmp32s = GD->sdword[0];

+            tmp8u=tmp32s&(rex.w?63:31);

+            tmp32s >>= (rex.w?6:5);

             if(!MODREG)

             {

-                ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5));

+                ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2)));

             }

             if(rex.w) {

-                tmp8u&=63;

                 if(ED->q[0] & (1LL<<tmp8u)) {

                     SET_FLAG(F_CF);

                     ED->q[0] ^= (1LL<<tmp8u);

                 } else

                     CLEAR_FLAG(F_CF);

             } else {

-                tmp8u&=31;

                 if(ED->dword[0] & (1<<tmp8u)) {

                     SET_FLAG(F_CF);

                     ED->dword[0] ^= (1<<tmp8u);

@@ -926,8 +926,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     CHECK_FLAGS(emu);

                     GETED(1);

                     tmp8u = F8;

-                    if(!MODREG)

-                        ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5));

                     if(rex.w) {

                         tmp8u&=63;

                         if(ED->q[0] & (1LL<<tmp8u))

@@ -946,8 +944,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     CHECK_FLAGS(emu);

                     GETED(1);

                     tmp8u = F8;

-                    if(!MODREG)

-                        ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5));

                     if(rex.w) {

                         tmp8u&=63;

                         if(ED->q[0] & (1LL<<tmp8u)) {

@@ -970,8 +966,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     CHECK_FLAGS(emu);

                     GETED(1);

                     tmp8u = F8;

-                    if(!MODREG)

-                        ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5));

                     if(rex.w) {

                         tmp8u&=63;

                         if(ED->q[0] & (1LL<<tmp8u)) {

@@ -992,8 +986,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     CHECK_FLAGS(emu);

                     GETED(1);

                     tmp8u = F8;

-                    if(!MODREG)

-                        ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5));

                     if(rex.w) {

                         tmp8u&=63;

                         if(ED->q[0] & (1LL<<tmp8u))

@@ -1020,23 +1012,20 @@ int Run0F(x64emu_t *emu, rex_t rex)
             nextop = F8;

             GETED(0);

             GETGD;

-            tmp8u = GD->byte[0];

+            tmp32s = GD->sdword[0];

+            tmp8u=tmp32s&(rex.w?63:31);

+            tmp32s >>= (rex.w?6:5);

             if(!MODREG)

             {

-                if(rex.w)

-                    ED=(reg64_t*)(((uint64_t*)(ED))+(tmp8u>>6));

-                else

-                    ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5));

+                ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2)));

             }

             if(rex.w) {

-                tmp8u&=63;

                 if(ED->q[0] & (1LL<<tmp8u))

                     SET_FLAG(F_CF);

                 else

                     CLEAR_FLAG(F_CF);

                 ED->q[0] ^= (1LL<<tmp8u);

             } else {

-                tmp8u&=31;

                 if(ED->dword[0] & (1<<tmp8u))

                     SET_FLAG(F_CF);

                 else

diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 9b23c1f2..be9b29ca 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -756,13 +756,20 @@ int Run660F(x64emu_t *emu, rex_t rex)
         nextop = F8;

         GETEW(0);

         GETGW;

+        tmp32s = rex.w?GW->sdword[0]:GW->sword[0];

+        tmp8u=tmp32s&(rex.w?63:15);

+        tmp32s >>= (rex.w?6:4);

+        if(!MODREG)

+        {

+            EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1)));

+        }

         if(rex.w) {

-            if(EW->q[0] & (1LL<<(GW->q[0]&63)))

+            if(EW->q[0] & (1LL<<tmp8u))

                 SET_FLAG(F_CF);

             else

                 CLEAR_FLAG(F_CF);

         } else {

-            if(EW->word[0] & (1<<(GW->word[0]&15)))

+            if(EW->word[0] & (1<<tmp8u))

                 SET_FLAG(F_CF);

             else

                 CLEAR_FLAG(F_CF);

@@ -788,18 +795,25 @@ int Run660F(x64emu_t *emu, rex_t rex)
         nextop = F8;

         GETEW(0);

         GETGW;

+        tmp32s = rex.w?GW->sdword[0]:GW->sword[0];

+        tmp8u=tmp32s&(rex.w?63:15);

+        tmp32s >>= (rex.w?6:4);

+        if(!MODREG)

+        {

+            EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1)));

+        }

         if(rex.w) {

-            if(EW->q[0] & (1LL<<(GW->q[0]&63)))

+            if(EW->q[0] & (1LL<<tmp8u))

                 SET_FLAG(F_CF);

             else {

-                EW->q[0] |= (1LL<<(GW->q[0]&63));

+                EW->q[0] |= (1LL<<tmp8u);

                 CLEAR_FLAG(F_CF);

             }

         } else {

-            if(EW->word[0] & (1<<(GW->word[0]&15)))

+            if(EW->word[0] & (1<<tmp8u))

                 SET_FLAG(F_CF);

             else {

-                EW->word[0] |= (1<<(GW->word[0]&15));

+                EW->word[0] |= (1<<tmp8u);

                 CLEAR_FLAG(F_CF);

             }

         }

@@ -855,16 +869,23 @@ int Run660F(x64emu_t *emu, rex_t rex)
         nextop = F8;

         GETEW(0);

         GETGW;

+        tmp32s = rex.w?GW->sdword[0]:GW->sword[0];

+        tmp8u=tmp32s&(rex.w?63:15);

+        tmp32s >>= (rex.w?6:4);

+        if(!MODREG)

+        {

+            EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1)));

+        }

         if(rex.w) {

-            if(EW->q[0] & (1LL<<(GW->q[0]&63))) {

+            if(EW->q[0] & (1LL<<tmp8u)) {

                 SET_FLAG(F_CF);

-                EW->q[0] ^= (1LL<<(GW->q[0]&63));

+                EW->q[0] ^= (1LL<<tmp8u);

             } else

                 CLEAR_FLAG(F_CF);

         } else {

-            if(EW->word[0] & (1<<(GW->word[0]&15))) {

+            if(EW->word[0] & (1<<tmp8u)) {

                 SET_FLAG(F_CF);

-                EW->word[0] ^= (1<<(GW->word[0]&15));

+                EW->word[0] ^= (1<<tmp8u);

             } else

                 CLEAR_FLAG(F_CF);

         }

@@ -882,11 +903,26 @@ int Run660F(x64emu_t *emu, rex_t rex)
         nextop = F8;

         GETEW(0);

         GETGW;

-        if(EW->word[0] & (1<<(GW->word[0]&15)))

-            SET_FLAG(F_CF);

-        else

-            CLEAR_FLAG(F_CF);

-        EW->word[0] ^= (1<<(GW->word[0]&15));

+        tmp32s = rex.w?GW->sdword[0]:GW->sword[0];

+        tmp8u=tmp32s&(rex.w?63:15);

+        tmp32s >>= (rex.w?6:4);

+        if(!MODREG)

+        {

+            EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1)));

+        }

+        if(rex.w) {

+            if(EW->q[0] & (1LL<<tmp8u))

+                SET_FLAG(F_CF);

+            else

+                CLEAR_FLAG(F_CF);

+            EW->q[0] ^= (1LL<<tmp8u);

+        } else {

+            if(EW->word[0] & (1<<tmp8u))

+                SET_FLAG(F_CF);

+            else

+                CLEAR_FLAG(F_CF);

+            EW->word[0] ^= (1<<tmp8u);

+        }

         break;

     case 0xBC:                      /* BSF Ew,Gw */

         CHECK_FLAGS(emu);