about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-04-10 20:10:58 +0800
committerGitHub <noreply@github.com>2023-04-10 14:10:58 +0200
commit9b3511cc88ea3c03590ccd9158095086de53c9ed (patch)
tree5fd07d08586578d5c31c6e07cd01211471b45373 /src
parent48f80ebc930e66968e36e75425dae44490040a97 (diff)
downloadbox64-9b3511cc88ea3c03590ccd9158095086de53c9ed.tar.gz
box64-9b3511cc88ea3c03590ccd9158095086de53c9ed.zip
[RV64_DYNAREC] Added more opcode for SV and some fixes (#683)
* [RV64_DYNAREC] Added 66 0F 67 PACKUSWB opcode

* [RV64_DYNAREC] Added 66 0F 6B PACKSSDW opcode

* [INTERP] Fixed typos

* [RV64_DYNAREC] Fixed 0F BA /7 BTC opcode

* [RV64_DYNAREC] Added 0F BB BTC opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c40
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c65
-rw-r--r--src/emu/x64run0f.c14
3 files changed, 112 insertions, 7 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index a1ef5734..b2bf4df4 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -538,11 +538,51 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MOV64xw(x3, (1LL << u8));
                         XOR(ed, ed, x3);
                     }
+                    if(wback) {
+                        SDxw(ed, wback, fixedaddress);
+                        SMWRITE();
+                    }
                     break;
                 default:
                     DEFAULT;
             }
             break;
+        case 0xBB:
+            INST_NAME("BTC Ed, Gd");
+            SETFLAGS(X_CF, SF_SUBSET);
+            SET_DFNONE();
+            nextop = F8;
+            GETGD;
+            if (MODREG) {
+                ed = xRAX+(nextop&7)+(rex.b<<3);
+                wback = 0;
+            } else {
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
+                SRAI(x1, gd, 5+rex.w);
+                SLLI(x1, x1, 2+rex.w);
+                ADD(x3, wback, x1);
+                LDxw(x1, x3, fixedaddress);
+                ed = x1;
+                wback = x3;
+            }
+            if (rex.w) {
+                ANDI(x2, gd, 0x3f);
+            } else {
+                ANDI(x2, gd, 0x1f);
+            }
+            SRL(x4, ed, x2);
+            ANDI(x4, x4, 1); // F_CF is 1
+            ANDI(xFlags, xFlags, ~1);
+            OR(xFlags, xFlags, x4);
+            ADDI(x3, xZR, 1);
+            SLL(x3, x3, x2);
+            XOR(ed, ed, x3);
+            if(wback) {
+                SDxw(ed, wback, fixedaddress);
+                SMWRITE();
+            }
+            break;
         case 0xBE:
             INST_NAME("MOVSX Gd, Eb");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 9c32068f..a2212e9a 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -244,6 +244,39 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGX(x2);
             SSE_LOOP_DS(x3, x4, SLT(x4, x4, x3); SLLI(x3, x4, 63); SRAI(x3, x3, 63));
             break;
+        case 0x67:
+            INST_NAME("PACKUSWB Gx, Ex");
+            nextop = F8;
+            GETEX(x1, 0);
+            GETGX(x2);
+            ADDI(x5, xZR, 0xFF);
+            for(int i=0; i<8; ++i) {
+                // GX->ub[i] = (GX->sw[i]<0)?0:((GX->sw[i]>0xff)?0xff:GX->sw[i]);
+                LH(x3, gback, i*2);
+                BGE(x5, x3, 8);
+                ADDI(x3, xZR, 0xFF);
+                NOT(x4, x3);
+                SRAI(x4, x4, 63);
+                AND(x3, x3, x4);
+                SB(x3, gback, i);
+            }
+            if (MODREG && (ed==gd)) {
+                // GX->q[1] = GX->q[0];
+                LD(x3, gback, 0*8);
+                SD(x3, gback, 1*8);
+            } else {
+                for(int i=0; i<8; ++i) {
+                    // GX->ub[8+i] = (EX->sw[i]<0)?0:((EX->sw[i]>0xff)?0xff:EX->sw[i]);
+                    LH(x3, wback, fixedaddress+i*2);
+                    BGE(x5, x3, 8);
+                    ADDI(x3, xZR, 0xFF);
+                    NOT(x4, x3);
+                    SRAI(x4, x4, 63);
+                    AND(x3, x3, x4);
+                    SB(x3, gback, 8+i);
+                }
+            }
+            break;
         case 0x69:
             INST_NAME("PUNPCKHWD Gx,Ex");
             nextop = F8;
@@ -288,6 +321,38 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SW(x3, gback, 3*4);
             }
             break;
+        case 0x6B:
+            INST_NAME("PACKSSDW Gx,Ex");
+            nextop = F8;
+            GETEX(x1, 0);
+            GETGX(x2);
+            MOV64x(x5, 32768);
+            NEG(x6, x5);
+            for(int i=0; i<4; ++i) {
+                // GX->sw[i] = (GX->sd[i]<-32768)?-32768:((GX->sd[i]>32767)?32767:GX->sd[i]);
+                LW(x3, gback, i*4);
+                BGE(x5, x3, 8);
+                ADDI(x3, x5, -1);
+                BGE(x3, x6, 8);
+                MV(x3, x6);
+                SH(x3, gback, i*2);
+            }
+            if (MODREG && (ed==gd)) {
+                // GX->q[1] = GX->q[0];
+                LD(x3, gback, 0*8);
+                SD(x3, gback, 1*8);
+            } else {
+                for(int i=0; i<4; ++i) {
+                    // GX->sw[4+i] = (EX->sd[i]<-32768)?-32768:((EX->sd[i]>32767)?32767:EX->sd[i]);
+                    LW(x3, wback, fixedaddress+i*4);
+                    BGE(x5, x3, 8);
+                    ADDI(x3, x5, -1);
+                    BGE(x3, x6, 8);
+                    MV(x3, x6);
+                    SH(x3, gback, (4+i)*2);
+                }
+            }
+            break;
         case 0x6C:
             INST_NAME("PUNPCKLQDQ Gx,Ex");
             nextop = F8;
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 8cd5b312..5f46db5d 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -876,13 +876,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             if(!MODREG)

             {

                 #ifdef TEST_INTERPRETER

-                test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2)));

+                test->memaddr=((test->memaddr)+(tmp64s<<(rex.w?3:2)));

                 if(rex.w)

                     *(uint64_t*)test->mem = *(uint64_t*)test->memaddr;

                 else

                     *(uint32_t*)test->mem = *(uint32_t*)test->memaddr;

                 #else

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

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

                 #endif

             }

             if(rex.w) {

@@ -1022,13 +1022,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             if(!MODREG)

             {

                 #ifdef TEST_INTERPRETER

-                test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2)));

+                test->memaddr=((test->memaddr)+(tmp64s<<(rex.w?3:2)));

                 if(rex.w)

                     *(uint64_t*)test->mem = *(uint64_t*)test->memaddr;

                 else

                     *(uint32_t*)test->mem = *(uint32_t*)test->memaddr;

                 #else

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

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

                 #endif

             }

             if(rex.w) {

@@ -1160,13 +1160,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             if(!MODREG)

             {

                 #ifdef TEST_INTERPRETER

-                test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2)));

+                test->memaddr=((test->memaddr)+(tmp64s<<(rex.w?3:2)));

                 if(rex.w)

                     *(uint64_t*)test->mem = *(uint64_t*)test->memaddr;

                 else

                     *(uint32_t*)test->mem = *(uint32_t*)test->memaddr;

                 #else

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

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

                 #endif

             }

             if(rex.w) {

@@ -1729,4 +1729,4 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             return 0;

     }

     return addr;

-}
\ No newline at end of file
+}