diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/arm64_printer.c | 13 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_dd.c | 9 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_df.c | 26 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_functions.c | 8 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 6 | ||||
| -rw-r--r-- | src/emu/x87emu_private.h | 4 |
7 files changed, 44 insertions, 24 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index f86a93ec..be7bf0c7 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -1150,7 +1150,9 @@ int convert_bitmask(uint64_t bitmask); #define VFMOVDQ_8(Vd, u8) EMIT(FMOV_vector_imm(1, 1, ((u8)>>5)&0b111, (u8)&0b11111, Vd)) #define FMOV_scalar_imm(type, imm8, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | (imm8)<<13 | 0b100<<10 | (Rd)) +// FMOV to Sd, imm=7 :~6:6:6:6:6:6:5:4 :3:2:1:0.... #define FMOVS_8(Sd, u8) EMIT(FMOV_scalar_imm(0b00, u8, Sd)) +// FMOV to Dd, imm=7 :~6:6:6:6:6:6:6:6:6:5:4 :3:2:1:0.... #define FMOVD_8(Dd, u8) EMIT(FMOV_scalar_imm(0b01, u8, Dd)) // VMOV diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c index 2d28a831..0b043886 100644 --- a/src/dynarec/arm64/arm64_printer.c +++ b/src/dynarec/arm64/arm64_printer.c @@ -743,8 +743,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], lsb, width); else snprintf(buff, sizeof(buff), "BFI %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], lsb, width); - } else - snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1); + } else { + if(Rn==31 && immr==0) + snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], immr, imms-immr+1); + else + snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1); + } return buff; } // ---- BRANCH / TEST @@ -1643,6 +1647,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "%cQXTN%s V%d.%s, V%d.%s", a.U?'U':'S', a.Q?"2":"", Rd, Vd, Rn, Va); return buff; } + if(isMask(opcode, "01U11110ff100001010010nnnnnddddd", &a)) { + const char Z[] = {'B', 'H', 'S', 'D', '?'}; + snprintf(buff, sizeof(buff), "SQXT%sN %c%d, %c%d", a.U?"U":"", Z[sf], Rn, Z[sf+1], Rm); + return buff; + } // (S/U)SSHL(2) / (U/S)XTL(2) if(isMask(opcode, "0QU011110hhhhiii101001nnnnnddddd", &a)) { diff --git a/src/dynarec/arm64/dynarec_arm64_dd.c b/src/dynarec/arm64/dynarec_arm64_dd.c index 33282abd..6e93c789 100644 --- a/src/dynarec/arm64/dynarec_arm64_dd.c +++ b/src/dynarec/arm64/dynarec_arm64_dd.c @@ -161,19 +161,20 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin s0 = fpu_get_scratch(dyn, ninst); if(arm64_frintts) { FRINT64ZD(s0, v1); - FCVTZSxD(x2, s0); - STx(x2, ed, fixedaddress); + VFCVTZSd(s0, s0); + VST64(s0, ed, fixedaddress); } else { MRS_fpsr(x5); BFCw(x5, FPSR_IOC, 1); // reset IOC bit MSR_fpsr(x5); FRINTRRD(s0, v1, 3); - FCVTZSxD(x2, s0); + VFCVTZSd(s0, s0); + VST64(s0, ed, fixedaddress); MRS_fpsr(x5); // get back FPSR to check the IOC bit TBZ_MARK3(x5, FPSR_IOC); ORRx_mask(x2, xZR, 1, 1, 0); //0x8000000000000000 - MARK3; STx(x2, ed, fixedaddress); + MARK3; } } X87_POP_OR_FAIL(dyn, ninst, x3); diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c index 62bdbac7..dd03a515 100644 --- a/src/dynarec/arm64/dynarec_arm64_df.c +++ b/src/dynarec/arm64/dynarec_arm64_df.c @@ -356,16 +356,22 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin B_MARK3(c__); MARK2; } - MRS_fpsr(x5); - BFCw(x5, FPSR_IOC, 1); // reset IOC bit - MSR_fpsr(x5); - FRINTXD(s0, v1); - VFCVTZSd(s0, s0); - VST64(s0, wback, fixedaddress); - MRS_fpsr(x5); // get back FPSR to check the IOC bit - TBZ_MARK3(x5, FPSR_IOC); - ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000 - STx(x5, wback, fixedaddress); + if(arm64_frintts) { + FRINT64XD(s0, v1); + VFCVTZSd(s0, s0); + VST64(s0, wback, fixedaddress); + } else { + MRS_fpsr(x5); + BFCw(x5, FPSR_IOC, 1); // reset IOC bit + MSR_fpsr(x5); + FRINTXD(s0, v1); + VFCVTZSd(s0, s0); + VST64(s0, wback, fixedaddress); + MRS_fpsr(x5); // get back FPSR to check the IOC bit + TBZ_MARK3(x5, FPSR_IOC); + ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000 + STx(x5, wback, fixedaddress); + } MARK3; #endif x87_restoreround(dyn, ninst, u8); diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c index 28673221..2a7a2a09 100644 --- a/src/dynarec/arm64/dynarec_arm64_functions.c +++ b/src/dynarec/arm64/dynarec_arm64_functions.c @@ -926,9 +926,9 @@ uint8_t mark_natflag(dynarec_arm_t* dyn, int ninst, uint8_t flag, int before) { if(dyn->insts[ninst].x64.set_flags && !before) { dyn->insts[ninst].set_nat_flags |= flag; - if(dyn->insts[ninst].x64.use_flags) { - dyn->insts[ninst].use_nat_flags |= flag; - } + //if(dyn->insts[ninst].x64.use_flags) { + // dyn->insts[ninst].use_nat_flags |= flag; + //} } else { if(before) dyn->insts[ninst].use_nat_flags_before |= flag; @@ -1098,7 +1098,7 @@ void updateNativeFlags(dynarec_native_t* dyn) { if(!box64_dynarec_nativeflags) return; - // backward check if native flags are used + // forward check if native flags are used for(int ninst=0; ninst<dyn->size; ++ninst) if(flag2native(dyn->insts[ninst].x64.gen_flags) && (dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH)) { propagateNativeFlags(dyn, ninst); diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 2da90d59..f47ecaf7 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -950,7 +950,8 @@ MOV32w(s2, 0b01000101); /* unordered */ \ CSELw(s1, s2, s1, cVS); \ if(v1||v2) { \ - Bcond(cVS, 10*4); \ + Bcond(cVS, 11*4); \ + Bcond(cEQ, 10*4); \ if(is_f) { \ ORRw_mask(s4, xZR, 12, 10); /*+inf*/ \ FMOVwS(s2, v1); \ @@ -996,7 +997,8 @@ CSELw(s1, s2, s1, cEQ); \ /* greater than leave 0 */ \ if(s4) { \ - Bcond(cVS, 10*4); \ + Bcond(cVS, 11*4); \ + Bcond(cEQ, 10*4); \ if(is_f) { \ ORRw_mask(s4, xZR, 12, 10); /*+inf*/ \ FMOVwS(s2, v1); \ diff --git a/src/emu/x87emu_private.h b/src/emu/x87emu_private.h index e3f0d233..17691c49 100644 --- a/src/emu/x87emu_private.h +++ b/src/emu/x87emu_private.h @@ -73,7 +73,7 @@ static inline void fpu_fcom(x64emu_t* emu, double b) emu->sw.f.F87_C0 = 1; emu->sw.f.F87_C2 = 1; emu->sw.f.F87_C3 = 1; - } else if ((b==-INFINITY) || (ST0.d==INFINITY)) { + } else if (((b==-INFINITY) || (ST0.d==INFINITY)) && ST0.d!=b) { emu->sw.f.F87_C0 = 0; emu->sw.f.F87_C2 = 0; emu->sw.f.F87_C3 = 0; @@ -104,7 +104,7 @@ static inline void fpu_fcomi(x64emu_t* emu, double b) SET_FLAG(F_CF); SET_FLAG(F_PF); SET_FLAG(F_ZF); - } else if ((b==-INFINITY) || (ST0.d==INFINITY)) { + } else if (((b==-INFINITY) || (ST0.d==INFINITY)) && ST0.d!=b) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_ZF); |