about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-07 10:40:46 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-07 10:40:46 +0100
commita1ff40733bf1cd883e1871ea1ed5897b9f608106 (patch)
treec8e546da7d159f681d0cdea25370473b52ee1b7c /src
parenta61888e06cd4dadc06717b8ca58c161f85ce7fb8 (diff)
downloadbox64-a1ff40733bf1cd883e1871ea1ed5897b9f608106.tar.gz
box64-a1ff40733bf1cd883e1871ea1ed5897b9f608106.zip
[ARM64_DYNAREC] Optimized 8bits XOR when no flags is needed
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index dc04a661..2dc8f66e 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -507,10 +507,23 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("XOR Eb, Gb");
             SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETEB(x1, 0);
-            GETGB(x2);
-            emit_xor8(dyn, ninst, x1, x2, x4, x5);
-            EBBACK;
+            UFLAG_IF {
+                GETEB(x1, 0);
+                GETGB(x2);
+                emit_xor8(dyn, ninst, x1, x2, x4, x5);
+                EBBACK;
+            } else {
+                if(MODREG) {
+                    GETGB(x2);
+                    CALCEB();
+                    EORx_REG_LSL(wback, wback, x2, wb2);
+                } else {
+                    GETEB(x1, 0);
+                    CALCGB();
+                    EORw_REG_LSR(x1, x1, gb1, 8*gb2);
+                    EBBACK;
+                }
+            }
             break;
         case 0x31:
             INST_NAME("XOR Ed, Gd");
@@ -525,10 +538,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("XOR Gb, Eb");
             SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETEB(x2, 0);
-            GETGB(x1);
-            emit_xor8(dyn, ninst, x1, x2, x3, x4);
-            GBBACK;
+            UFLAG_IF {
+                GETEB(x2, 0);
+                GETGB(x1);
+                emit_xor8(dyn, ninst, x1, x2, x3, x4);
+                GBBACK;
+            } else {
+                GETEB(x2, 0);
+                CALCGB();
+                EORx_REG_LSL(gb1, gb1, x2, gb2*8);
+            }
             break;
         case 0x33:
             INST_NAME("XOR Gd, Ed");
@@ -542,9 +561,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("XOR AL, Ib");
             SETFLAGS(X_ALL, SF_SET_PENDING);
             u8 = F8;
-            UXTBw(x1, xRAX);
-            emit_xor8c(dyn, ninst, x1, u8, x3, x4);
-            BFIx(xRAX, x1, 0, 8);
+            UFLAG_IF {
+                UXTBw(x1, xRAX);
+                emit_xor8c(dyn, ninst, x1, u8, x3, x4);
+                BFIx(xRAX, x1, 0, 8);
+            } else {
+                int mask = convert_bitmask_x(u8);
+                if(mask)
+                    EORx_mask(xRAX, xRAX, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
+                else {
+                    MOV32w(x1, u8);
+                    EORx_REG(xRAX, xRAX, x1);
+                }
+            }
             break;
         case 0x35:
             INST_NAME("XOR EAX, Id");
@@ -1107,10 +1136,22 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6: //XOR
                     INST_NAME("XOR Eb, Ib");
                     SETFLAGS(X_ALL, SF_SET_PENDING);
-                    GETEB(x1, 1);
-                    u8 = F8;
-                    emit_xor8c(dyn, ninst, x1, u8, x2, x4);
-                    EBBACK;
+                    UFLAG_IF2(|| !MODREG) {
+                        GETEB(x1, 1);
+                        u8 = F8;
+                        emit_xor8c(dyn, ninst, x1, u8, x2, x4);
+                        EBBACK;
+                    } else {
+                        CALCEB();
+                        u8 = F8;
+                        int mask = convert_bitmask_x(((uint32_t)u8)<<wb2);
+                        if(mask)
+                            EORx_mask(wback, wback, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
+                        else {
+                            MOV32w(x1, ((uint32_t)u8)<<wb2);
+                            EORx_REG(wback, wback, x1);
+                        }
+                    }
                     break;
                 case 7: //CMP
                     INST_NAME("CMP Eb, Ib");