diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-07-03 13:35:17 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-07-03 13:35:17 +0200 |
| commit | a6f0525a4c2d96d2f54707369acc75e54d4d6574 (patch) | |
| tree | 0a4bb96ef4c845ef2eb9499898a7b9a9e53d44dc /src | |
| parent | d9707926faa80a1c25609e7a7dfa40d82d43f0a1 (diff) | |
| download | box64-a6f0525a4c2d96d2f54707369acc75e54d4d6574.tar.gz box64-a6f0525a4c2d96d2f54707369acc75e54d4d6574.zip | |
Added 64 66 0F 2E/2F ocodes ([DYNAREC] too) (for #298)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/arm64_emitter.h | 8 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_6664.c | 21 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 26 |
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) { |