about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-03 11:34:11 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-03 11:34:11 +0100
commit7c0995726327511079bdec0454ae7b6687f16cfe (patch)
tree88b9981c759a5f4f58c84b470af630dc529e74aa /src
parent242832fa3c8ef37c9c623165f72b5d1bc79b88b4 (diff)
downloadbox64-7c0995726327511079bdec0454ae7b6687f16cfe.tar.gz
box64-7c0995726327511079bdec0454ae7b6687f16cfe.zip
[ARM64_DYNAREC] Small optims on a few 66 prefixed opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h1
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c42
2 files changed, 27 insertions, 16 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 3b336b57..4b57ab88 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -713,6 +713,7 @@ int convert_bitmask(uint64_t bitmask);
 #define BFCx(Rd, lsb, width)            BFMx(Rd, xZR, ((-(lsb))%64)&0x3f, (width)-1)
 #define BFCw(Rd, lsb, width)            BFMw(Rd, xZR, ((-(lsb))%32)&0x1f, (width)-1)
 #define BFCxw(Rd, lsb, width)           BFMxw(Rd, xZR, rex.w?(((-(lsb))%64)&0x3f):(((-(lsb))%32)&0x1f), (width)-1)
+#define BFCz(Rd, lsb, width)            if(rex.is32bits) {BFCw(Rd, lsb, width);} else {BFCx(Rd, lsb, width);}
 // Insert lsb:width part of Rn into low part of Rd (leaving rest of Rd untouched)
 #define BFXILx(Rd, Rn, lsb, width)      EMIT(BFM_gen(1, 0b01, 1, (lsb), (lsb)+(width)-1, Rn, Rd))
 // Insert lsb:width part of Rn into low part of Rd (leaving rest of Rd untouched)
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 192c7c1e..d8f95a35 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -447,7 +447,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             UFLAG_IF {

                 SET_DFNONE();

                 IFX(X_CF|X_OF) {

-                    ASRxw(x1, x2, 16);

+                    ASRw(x1, x2, 16);

                     CMPSw_REG_ASR(x1, x2, 31);

                     CSETw(x3, cNE);

                     IFX(X_CF) {

@@ -467,8 +467,8 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0x6A:

             INST_NAME("PUSH Ib");

-            u16 = (uint16_t)F8S;

-            MOV32w(x2, u16);

+            i16 = F8S;

+            MOV32w(x2, (uint16_t)i16);

             PUSH1_16(x2);

             break;

 

@@ -736,11 +736,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("POPF");

             SETFLAGS(X_ALL, SF_SET);

             SMREAD();

-            POP1_16(x1);    // probably not usefull...

+            POP1_16(x1);

+            MOV32w(x2, 0x7FD7);

+            ANDw_REG(x1, x1, x2);

+            ORRw_mask(x1, x1, 0b011111, 0);   //mask=0x00000002

             BFIw(xFlags, x1, 0, 16);

-            MOV32w(x1, 0x3F7FD7);

-            ANDw_REG(xFlags, xFlags, x1);

-            ORRw_mask(xFlags, xFlags, 0b011111, 0);   //mask=0x00000002

             SET_DFNONE();

             if(box64_wine) {    // should this be done all the time?

                 TBZ_NEXT(xFlags, F_TF);

@@ -750,7 +750,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

 

         case 0xA1:

-            INST_NAME("MOV EAX,Od");

+            INST_NAME("MOV AX,Od");

             if(rex.is32bits)

                 u64 = F32;

             else

@@ -763,7 +763,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

 

         case 0xA3:

-            INST_NAME("MOV Od,EAX");

+            INST_NAME("MOV Od,AX");

             if(rex.is32bits)

                 u64 = F32;

             else

@@ -980,9 +980,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xBF:

             INST_NAME("MOV Reg16, Iw");

             u16 = F16;

-            MOV32w(x1, u16);

             gd = TO_NAT((opcode & 7) + (rex.b << 3));

-            BFIz(gd, x1, 0, 16);

+            if(u16) {

+                MOV32w(x1, u16);

+                BFIz(gd, x1, 0, 16);

+            } else

+                BFCz(gd, 0, 16);

             break;

 

         case 0xC1:

@@ -1092,13 +1095,20 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             if(MODREG) {

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

                 u16 = F16;

-                MOV32w(x1, u16);

-                BFIz(ed, x1, 0, 16);

+                if(u16) {

+                    MOV32w(x1, u16);

+                    BFIz(ed, x1, 0, 16);

+                } else

+                    BFCz(ed, 0, 16);

             } else {

                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 2);

                 u16 = F16;

-                MOV32w(x1, u16);

-                STH(x1, ed, fixedaddress);

+                if(u16) {

+                    MOV32w(x1, u16);

+                    STH(x1, ed, fixedaddress);

+                } else {

+                    STH(xZR, ed, fixedaddress);

+                }

                 SMWRITELOCK(lock);

             }

             break;

@@ -1403,7 +1413,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     UFLAG_IF {

                         SET_DFNONE();

                         IFX(X_CF|X_OF) {

-                            ASRxw(x2, x1, 16);

+                            ASRw(x2, x1, 16);

                             CMPSw_REG_ASR(x2, x1, 31);

                             CSETw(x3, cNE);

                             IFX(X_CF) {