about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-06-01 11:38:32 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-06-01 11:38:32 +0200
commit9f260eb86c9d905a8c8796d89bcccb415dccbe95 (patch)
tree1c5dfade37e8471461141dbf27387a35b53e06cb /src
parent75878b24cd87ceda99df7b93c410056d176d6c70 (diff)
downloadbox64-9f260eb86c9d905a8c8796d89bcccb415dccbe95.tar.gz
box64-9f260eb86c9d905a8c8796d89bcccb415dccbe95.zip
[ARM64_DYNAREC] Fix issue with 66 0F 38 DC-DF when rare case of dest==src
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index 79173acf..3ed61e95 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -800,12 +800,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         VEORQ(q0, v0, q1);

                     } else {

                         GETG;

+                        GETEX(q1, 0, 0);

+                        if(MODREG && (gd==(nextop&7)+(rex.b<<3))) {

+                            d0 = fpu_get_scratch(dyn, ninst);

+                            VMOVQ(d0, q1);

+                        } else d0 = -1;

                         sse_forget_reg(dyn, ninst, gd);

                         MOV32w(x1, gd);

                         CALL(native_aese, -1);

                         GETGX(q0, 1);

-                        GETEX(q1, 0, 0);

-                        VEORQ(q0, q0, q1);

+                        VEORQ(q0, q0, (d0!=-1)?d0:q1);

                     }

                     break;

                 case 0xDD:

@@ -820,12 +824,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         VEORQ(q0, v0, q1);

                     } else {

                         GETG;

+                        GETEX(q1, 0, 0);

+                        if(MODREG && (gd==(nextop&7)+(rex.b<<3))) {

+                            d0 = fpu_get_scratch(dyn, ninst);

+                            VMOVQ(d0, q1);

+                        } else d0 = -1;

                         sse_forget_reg(dyn, ninst, gd);

                         MOV32w(x1, gd);

                         CALL(native_aeselast, -1);

                         GETGX(q0, 1);

-                        GETEX(q1, 0, 0);

-                        VEORQ(q0, q0, q1);

+                        VEORQ(q0, q0, (d0!=-1)?d0:q1);

                     }

                     break;

                 case 0xDE:

@@ -841,12 +849,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         VEORQ(q0, v0, q1);

                     } else {

                         GETG;

+                        GETEX(q1, 0, 0);

+                        if(MODREG && (gd==(nextop&7)+(rex.b<<3))) {

+                            d0 = fpu_get_scratch(dyn, ninst);

+                            VMOVQ(d0, q1);

+                        } else d0 = -1;

                         sse_forget_reg(dyn, ninst, gd);

                         MOV32w(x1, gd);

                         CALL(native_aesd, -1);

                         GETGX(q0, 1);

-                        GETEX(q1, 0, 0);

-                        VEORQ(q0, q0, q1);

+                        VEORQ(q0, q0, (d0!=-1)?d0:q1);

                     }

                     break;

                 case 0xDF:

@@ -861,12 +873,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         VEORQ(q0, v0, q1);

                     } else {

                         GETG;

+                        GETEX(q1, 0, 0);

+                        if(MODREG && (gd==(nextop&7)+(rex.b<<3))) {

+                            d0 = fpu_get_scratch(dyn, ninst);

+                            VMOVQ(d0, q1);

+                        } else d0 = -1;

                         sse_forget_reg(dyn, ninst, gd);

                         MOV32w(x1, gd);

                         CALL(native_aesdlast, -1);

                         GETGX(q0, 1);

-                        GETEX(q1, 0, 0);

-                        VEORQ(q0, q0, q1);

+                        VEORQ(q0, q0, (d0!=-1)?d0:q1);

                     }

                     break;

                 case 0xF0: