about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorxctan <xctan@cirno.icu>2024-11-26 15:21:57 +0800
committerGitHub <noreply@github.com>2024-11-26 08:21:57 +0100
commit48461001d2ecf5f7f5c99a8c2be414761e298841 (patch)
treeabb56029ca7031b2d786a6c5e96f2bdcf0428b04 /src
parent12649d04c75fabb6e2bdc0e659918f1b21bcf1ac (diff)
downloadbox64-48461001d2ecf5f7f5c99a8c2be414761e298841.tar.gz
box64-48461001d2ecf5f7f5c99a8c2be414761e298841.zip
[RV64_DYNAREC] Fixed vector packed logical shift opcodes (#2075)
* [RV64_DYNAREC] Fixed vector packed logical shift opcodes

* [RV64_DYNAREC] Fixed a operand violation in vector CVTSD2SS
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f_vector.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f_vector.c7
2 files changed, 8 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
index a6d5330c..ed29f3a8 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c
@@ -1779,10 +1779,10 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 i32 = 64;
             }
             nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
             GETGX_vector(q0, 1, VECTOR_SEW64);
             if (MODREG) {
                 q1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64);
-                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
                 VMV_X_S(x4, q1);
             } else {
                 SMREAD();
@@ -2133,9 +2133,9 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
                 i32 = 64;
             }
             nextop = F8;
+            SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
             GETGX_vector(q0, 1, VECTOR_SEW64);
             if (MODREG) {
-                SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
                 q1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64);
                 VMV_X_S(x4, q1);
             } else {
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
index 2fa61ce9..6c1678f6 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c
@@ -340,7 +340,12 @@ uintptr_t dynarec64_F20F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
             SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
             VECTOR_LOAD_VMASK(0b0001, x4, 1);
             d0 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2);
-            if (v1 & 1 || v0 == v1) {
+            // as per section 5.2 Vector Operands of V-spec v1.0,
+            // > A destination vector register group can overlap a source vector register group only if one of the following holds:
+            // > - ...
+            // > - The destination EEW is smaller than the source EEW and the overlap is in the lowest-numbered part of the source register group
+            // > - ...
+            if (v1 & 1 || v0 == v1 + 1) {
                 d1 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2);
                 VMV_V_V(d1, v1);
                 if (rv64_xtheadvector) {