about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/arm64_emitter.h8
-rw-r--r--src/dynarec/arm64/dynarec_arm64_6664.c21
-rw-r--r--src/emu/x64run64.c26
3 files changed, 51 insertions, 4 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index c88848a8..11d92321 100755
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -728,15 +728,15 @@
 #define VLDR32_REG_LSL3(Dt, Rn, Rm)         EMIT(VMEM_REG_gen(0b10, 0b01, Rm, 0b011, 1, Rn, Dt))
 #define VLDR64_REG(Dt, Rn, Rm)              EMIT(VMEM_REG_gen(0b11, 0b01, Rm, 0b011, 0, Rn, Dt))
 #define VLDR64_REG_LSL3(Dt, Rn, Rm)         EMIT(VMEM_REG_gen(0b11, 0b01, Rm, 0b011, 1, Rn, Dt))
-#define VLDR128_REG(Qt, Rn, Rm)             EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b011, 0, Rn, Dt))
-#define VLDR128_REG_LSL4(Qt, Rn, Rm)        EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b011, 1, Rn, Dt))
+#define VLDR128_REG(Qt, Rn, Rm)             EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b011, 0, Rn, Qt))
+#define VLDR128_REG_LSL4(Qt, Rn, Rm)        EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b011, 1, Rn, Qt))
 
 #define VSTR32_REG(Dt, Rn, Rm)              EMIT(VMEM_REG_gen(0b10, 0b00, Rm, 0b011, 0, Rn, Dt))
 #define VSTR32_REG_LSL3(Dt, Rn, Rm)         EMIT(VMEM_REG_gen(0b10, 0b00, Rm, 0b011, 1, Rn, Dt))
 #define VSTR64_REG(Dt, Rn, Rm)              EMIT(VMEM_REG_gen(0b11, 0b00, Rm, 0b011, 0, Rn, Dt))
 #define VSTR64_REG_LSL3(Dt, Rn, Rm)         EMIT(VMEM_REG_gen(0b11, 0b00, Rm, 0b011, 1, Rn, Dt))
-#define VSTR128_REG(Qt, Rn, Rm)             EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b011, 0, Rn, Dt))
-#define VSTR128_REG_LSL4(Qt, Rn, Rm)        EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b011, 1, Rn, Dt))
+#define VSTR128_REG(Qt, Rn, Rm)             EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b011, 0, Rn, Qt))
+#define VSTR128_REG_LSL4(Qt, Rn, Rm)        EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b011, 1, Rn, Qt))
 
 #define VLDR_PC_gen(opc, imm19, Rt)         ((opc)<<30 | 0b011<<27 | 1<<26 | (imm19)<<5 | (Rt))
 #define VLDR32_literal(Vt, imm19)           EMIT(VLDR_PC_gen(0b00, ((imm19)>>2)&0x7FFFF, Vt))
diff --git a/src/dynarec/arm64/dynarec_arm64_6664.c b/src/dynarec/arm64/dynarec_arm64_6664.c
index 4c5039c5..6fea4a4e 100644
--- a/src/dynarec/arm64/dynarec_arm64_6664.c
+++ b/src/dynarec/arm64/dynarec_arm64_6664.c
@@ -31,8 +31,10 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
     uint8_t opcode = F8;
     uint8_t nextop;
     uint8_t gd, ed;
+    int64_t j64;
     int v0, v1;
     int64_t fixedaddress;
+    MAYUSE(j64);
 
     // REX prefix before the 66 are ignored
     rex.rex = 0;
@@ -52,6 +54,25 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             opcode = F8;
             switch(opcode) {
 
+                case 0x2E:
+                    // no special check...
+                case 0x2F:
+                    if(opcode==0x2F) {INST_NAME("COMISD Gx, Ex");} else {INST_NAME("UCOMISD Gx, Ex");}
+                    SETFLAGS(X_ALL, SF_SET);
+                    nextop = F8;
+                    GETG;
+                    if(MODREG) {
+                        v0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
+                    } else {
+                        grab_segdata(dyn, addr, ninst, x4, _FS);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, NULL, 0, 0);
+                        v1 = fpu_get_scratch(dyn);                                                                       \
+                        VLDR128_REG(v1, ed, x4);
+                    }
+                    FCMPD(v0, v1);
+                    FCOMI(x1, x2);
+                    break;
+
             case 0xD6:
                 INST_NAME("MOVQ Ex, Gx");
                 nextop = F8;
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index af503324..3413fc81 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -172,6 +172,32 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                             return 1;

                     }

                     break;

+

+                case 0x2E:                      /* UCOMISD Gx, Ex */

+                    // no special check...

+                case 0x2F:                      /* COMISD Gx, Ex */

+                    switch(rep) {

+                        case 0:

+                            RESET_FLAGS(emu);

+                            nextop = F8;

+                            GETEX_OFFS(0, tlsdata);

+                            GETGX;

+                            if(isnan(GX->d[0]) || isnan(EX->d[0])) {

+                                SET_FLAG(F_ZF); SET_FLAG(F_PF); SET_FLAG(F_CF);

+                            } else if(isgreater(GX->d[0], EX->d[0])) {

+                                CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_CF);

+                            } else if(isless(GX->d[0], EX->d[0])) {

+                                CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_PF); SET_FLAG(F_CF);

+                            } else {

+                                SET_FLAG(F_ZF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_CF);

+                            }

+                            CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF);

+                            break;

+                        default:

+                            return 1;

+                    }

+                    break;

+

                 

                 case 0x59:

                     switch(rep) {