about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-10-30 04:01:14 +0800
committerGitHub <noreply@github.com>2024-10-29 21:01:14 +0100
commit1e34db98a854c0adf0e38de120c7df896c11f5f0 (patch)
tree23f7b4a3050d84ba73bfce82eaebeb6c1bf8b74e /src
parent9f821d6406f2e07bc4ffb1a123847aad2041a6b9 (diff)
downloadbox64-1e34db98a854c0adf0e38de120c7df896c11f5f0.tar.gz
box64-1e34db98a854c0adf0e38de120c7df896c11f5f0.zip
[RV64_DYNAREC] Added more opcodes for vector (#1978)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f_vector.c44
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f_vector.c38
2 files changed, 80 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
index 7435a468..d8036ed4 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c
@@ -378,6 +378,50 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
                 VADD_VX(q0, q1, xZR, VECTOR_MASKED);
             }
             break;
+        case 0xC2:
+            INST_NAME("CMPPS Gx, Ex, Ib");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+            GETGX_vector(v0, 1, VECTOR_SEW32);
+            GETEX_vector(v1, 0, 1, VECTOR_SEW32);
+            u8 = F8;
+            if ((u8 & 7) == 0) { // Equal
+                VMFEQ_VV(VMASK, v0, v1, VECTOR_UNMASKED);
+            } else if ((u8 & 7) == 4) { // Not Equal or unordered
+                VMFEQ_VV(VMASK, v0, v1, VECTOR_UNMASKED);
+                VXOR_VI(VMASK, VMASK, 0x1F, VECTOR_UNMASKED);
+            } else {
+                d0 = fpu_get_scratch(dyn);
+                VMFEQ_VV(VMASK, v0, v0, VECTOR_UNMASKED);
+                VMFEQ_VV(d0, v1, v1, VECTOR_UNMASKED);
+                VMAND_MM(VMASK, VMASK, d0);
+                switch (u8 & 7) {
+                    case 1: // Less than
+                        VMFLT_VV(d0, v0, v1, VECTOR_UNMASKED);
+                        VMAND_MM(VMASK, VMASK, d0);
+                        break;
+                    case 2: // Less or equal
+                        VMFLE_VV(d0, v0, v1, VECTOR_UNMASKED);
+                        VMAND_MM(VMASK, VMASK, d0);
+                        break;
+                    case 3: // NaN
+                        VXOR_VI(VMASK, VMASK, 0x1F, VECTOR_UNMASKED);
+                        break;
+                    case 5: // Greater or equal or unordered
+                        VMFLE_VV(d0, v1, v0, VECTOR_UNMASKED);
+                        VMORN_MM(VMASK, d0, VMASK);
+                        break;
+                    case 6: // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
+                        VMFLT_VV(d0, v1, v0, VECTOR_UNMASKED);
+                        VMORN_MM(VMASK, d0, VMASK);
+                        break;
+                    case 7: // Not NaN
+                        break;
+                }
+            }
+            VXOR_VV(v0, v0, v0, VECTOR_UNMASKED);
+            VXOR_VI(v0, v0, 0x1F, VECTOR_MASKED);
+            break;
         case 0xC6:
             INST_NAME("SHUFPS Gx, Ex, Ib");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c
index d5ac666a..c4f82e45 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c
@@ -124,6 +124,24 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
             break;
         case 0x38:
             return 0;
+        case 0x58:
+            INST_NAME("ADDSS Gx, Ex");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+            if (MODREG) {
+                GETGX_vector(v0, 1, VECTOR_SEW32);
+                v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW32);
+            } else {
+                SMREAD();
+                v1 = fpu_get_scratch(dyn);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                LWU(x4, ed, fixedaddress);
+                VMV_S_X(v1, x4);
+                GETGX_vector(v0, 1, VECTOR_SEW32);
+            }
+            VECTOR_LOAD_VMASK(0b0001, x4, 1);
+            VFADD_VV(v0, v0, v1, VECTOR_MASKED);
+            break;
         case 0x59:
             INST_NAME("MULSS Gx, Ex");
             nextop = F8;
@@ -136,7 +154,6 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 v1 = fpu_get_scratch(dyn);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
                 LWU(x4, ed, fixedaddress);
-                VXOR_VV(v1, v1, v1, VECTOR_UNMASKED);
                 VMV_S_X(v1, x4);
                 GETGX_vector(v0, 1, VECTOR_SEW32);
             }
@@ -177,7 +194,6 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 v1 = fpu_get_scratch(dyn);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
                 LWU(x4, ed, fixedaddress);
-                VXOR_VV(v1, v1, v1, VECTOR_UNMASKED);
                 VMV_S_X(v1, x4);
                 GETGX_vector(v0, 1, VECTOR_SEW32);
             }
@@ -192,6 +208,24 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 VMV_S_X(v0, x4);
             }
             break;
+        case 0x5C:
+            INST_NAME("SUBSS Gx, Ex");
+            nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
+            if (MODREG) {
+                GETGX_vector(v0, 1, VECTOR_SEW32);
+                v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW32);
+            } else {
+                SMREAD();
+                v1 = fpu_get_scratch(dyn);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                LWU(x4, ed, fixedaddress);
+                VMV_S_X(v1, x4);
+                GETGX_vector(v0, 1, VECTOR_SEW32);
+            }
+            VECTOR_LOAD_VMASK(0b0001, x4, 1);
+            VFSUB_VV(v0, v0, v1, VECTOR_MASKED);
+            break;
         case 0x5D:
             INST_NAME("MINSS Gx, Ex");
             nextop = F8;