about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2023-06-08 19:35:15 +0800
committerGitHub <noreply@github.com>2023-06-08 13:35:15 +0200
commit361de53d868cb2345c2df0275b8d148921c460b3 (patch)
tree9c27db6145e9be7855b3e3b4c914b928d9364df6 /src
parent4021f6d8c320c086fe7e6e4437414b646dda5062 (diff)
downloadbox64-361de53d868cb2345c2df0275b8d148921c460b3.tar.gz
box64-361de53d868cb2345c2df0275b8d148921c460b3.zip
[DYNAREC_RV64] Added more opcodes (#828)
* [RV64_DYNAREC] Added 64 0F 11 opcodes

* Added F2 0F F0 LDDQU opcode

* Added F3 0F 12 MOVSLDUP opcode

* Added 66 0F 38 DB AESIMC opcode

* Added F3 0F 53 RCPSS

* Added F5 CMC opcode

* Added 9F LAHF opcode

* Added 66 0F 38 10 PBLENDVB opcode

* Fixed typo

* Fxied typo

* Fixed review
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_64.c70
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c7
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c25
6 files changed, 136 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 5bfeec16..746488c6 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -509,6 +509,12 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 ANDI(xFlags, xFlags, ~(1<<F_TF));
             }
             break;
+        case 0x9F:
+            INST_NAME("LAHF");
+            READFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF);
+            ANDI(xRAX, xFlags, 0xFF);
+            SLLI(xRAX, xRAX, 8);
+            break;
         case 0xA1:
             INST_NAME("MOV EAX,Od");
             u64 = F64;
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 9019042e..ef933e6f 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -742,6 +742,12 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         case 0xF0:
             addr = dynarec64_F0(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
+        case 0xF5:
+            INST_NAME("CMC");
+            READFLAGS(X_CF);
+            SETFLAGS(X_CF, SF_SUBSET);
+            XORI(xFlags, xFlags, 1<<F_CF);
+            break;
         case 0xF6:
             nextop = F8;
             switch((nextop>>3)&7) {
diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c
index af49865b..fb73b049 100644
--- a/src/dynarec/rv64/dynarec_rv64_64.c
+++ b/src/dynarec/rv64/dynarec_rv64_64.c
@@ -33,12 +33,12 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
     uint8_t nextop;
     uint8_t u8;
     uint8_t gd, ed, eb1, eb2, gb1, gb2;
-    uint8_t wback, wb1, wb2, wb;
+    uint8_t gback, wback, wb1, wb2, wb;
     int64_t i64, j64;
     int v0, v1;
     int q0;
     int d0;
-    int64_t fixedaddress;
+    int64_t fixedaddress, gdoffset;
     int unscaled;
     MAYUSE(eb1);
     MAYUSE(eb2);
@@ -73,6 +73,72 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETEDO(x4, 0, x5);
             emit_add32(dyn, ninst, rex, gd, ed, x3, x4, x5);
             break;
+        case 0x0F:
+            opcode = F8;
+            switch(opcode) {
+                case 0x11:
+                    switch(rep) {
+                        case 0:
+                            INST_NAME("MOVUPS Ex,Gx");
+                            nextop = F8;
+                            GETGX();
+                            GETEX(x2, 0);
+                            if(!MODREG) {
+                                grab_segdata(dyn, addr, ninst, x4, seg);
+                                ADD(x4, x4, wback);
+                                wback = x4;
+                            }
+                            LD(x3, gback, gdoffset+0);
+                            LD(x5, gback, gdoffset+8);
+                            SD(x3, wback, fixedaddress+0);
+                            SD(x5, wback, fixedaddress+8);
+                            if(!MODREG)
+                                SMWRITE2();
+                            break;
+                        case 1:
+                            INST_NAME("MOVSD Ex, Gx");
+                            nextop = F8;
+                            GETG;
+                            v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
+                            if(MODREG) {
+                                ed = (nextop&7)+ (rex.b<<3);
+                                d0 = sse_get_reg(dyn, ninst, x1, ed, 0);
+                                FMVD(d0, v0);
+                            } else {
+                                grab_segdata(dyn, addr, ninst, x4, seg);
+                                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                                ADD(x4, x4, ed);
+                                ed = x4;
+                                FSD(v0, ed, fixedaddress);
+                                SMWRITE2();
+                            }
+                            break;
+                        case 2:
+                            INST_NAME("MOVSS Ex, Gx");
+                            nextop = F8;
+                            GETG;
+                            v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
+                            if(MODREG) {
+                                q0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 1);
+                                FMVS(q0, v0);
+                            } else {
+                                grab_segdata(dyn, addr, ninst, x4, seg);
+                                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                                ADD(x4, x4, ed);
+                                ed = x4;
+                                FSW(v0, ed, fixedaddress);
+                                SMWRITE2();
+                            }
+                            break;
+                        default:
+                            DEFAULT;
+                    }
+                    break;
+
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0x2B:
             INST_NAME("SUB Gd, Seg:Ed");
             SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 2b36300a..21c95103 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -368,7 +368,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         SH(x3, gback, gdoffset+i*2);
                     }
                     break;
-
+                case 0x10:
+                    INST_NAME("PBLENDVB Gx,Ex");
+                    nextop = F8;
+                    GETGX();
+                    GETEX(x2, 0);
+                    sse_forget_reg(dyn, ninst, 0); // forget xmm[0]
+                    for (int i=0; i<16; ++i) {
+                        LB(x3, xEmu, offsetof(x64emu_t, xmm[0])+i);
+                        BGE(x3, xZR, 12); // continue
+                        LBU(x3, wback, fixedaddress+i);
+                        SB(x3, gback, gdoffset+i);
+                        // continue
+                    }
+                    break;
                 case 0x17:
                     INST_NAME("PTEST Gx, Ex");
                     nextop = F8;
@@ -648,7 +661,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         SW(x3, gback, gdoffset+i*4);
                     }
                     break;
-
+                case 0xDB:
+                    INST_NAME("AESIMC Gx, Ex");  // AES-NI
+                    nextop = F8;
+                    GETGX();
+                    GETEX(x2, 0);
+                    SSE_LOOP_MV_Q(x3);
+                    sse_forget_reg(dyn, ninst, gd);
+                    MOV32w(x1, gd);
+                    CALL(native_aesimc, -1);
+                    break;
                 case 0xDC:
                     INST_NAME("AESENC Gx, Ex");  // AES-NI
                     nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
index 52716ad4..d532c6f5 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -364,6 +364,13 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             x87_restoreround(dyn, ninst, u8);
             SD(xZR, gback, gdoffset+8);
             break;
+        case 0xF0:
+            INST_NAME("LDDQU Gx,Ex");
+            nextop = F8;
+            GETGX();
+            GETEX(x2, 0);
+            SSE_LOOP_MV_Q(x3);
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index 0b0b0c31..383c6482 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -81,6 +81,21 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             }
             break;
 
+        case 0x12:
+            INST_NAME("MOVSLDUP Gx, Ex");
+            nextop = F8;
+            GETGX();
+            GETEX(x2, 0);
+
+            // GX->ud[1] = GX->ud[0] = EX->ud[0];
+            // GX->ud[3] = GX->ud[2] = EX->ud[2];
+            LD(x3, wback, fixedaddress+0);
+            SD(x3, gback, gdoffset+0);
+            SD(x3, gback, gdoffset+4);
+            LD(x3, wback, fixedaddress+8);
+            SD(x3, gback, gdoffset+8);
+            SD(x3, gback, gdoffset+12);
+            break;
         case 0x1E:
             INST_NAME("NOP / ENDBR32 / ENDBR64");
             nextop = F8;
@@ -153,6 +168,16 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGXSS_empty(v1);
             FSQRTS(v1, v0);
             break;
+        case 0x53:
+            INST_NAME("RCPSS Gx, Ex");
+            nextop = F8;
+            GETEXSS(v0, 0);
+            GETGXSS_empty(v1);
+            q0 = fpu_get_scratch(dyn);
+            LUI(x3, 0x3F800); // 1.0f
+            FMVWX(q0, x3);
+            FDIVS(v1, q0, v0);
+            break;
         case 0x58:
             INST_NAME("ADDSS Gx, Ex");
             nextop = F8;