From 32bfccce326ef85a9c678093216c5fd057df3083 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 20 Jan 2015 19:11:04 -0600 Subject: [PATCH] [AArch64] Fix bugs in floating point loadstores. The Backpatching routines didn't correctly understand where to find the real VFP register from, so in most cases it was using D0. Fixes bugs in the slowmem loadstore routines as well. --- .../PowerPC/JitArm64/JitArm64_BackPatch.cpp | 27 +++++++++++++++---- .../JitArm64/JitArm64_LoadStoreFloating.cpp | 6 +---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index ff185214ad..7c8552ac79 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -63,9 +63,18 @@ bool JitArm64::DisasmLoadStore(const u8* ptr, u32* flags, ARM64Reg* reg) { *flags &= ~BackPatchInfo::FLAG_SIZE_32; *flags |= BackPatchInfo::FLAG_SIZE_F32; + + // Loads directly in to the target register + // Duplicates bottom result in to top register + *reg = (ARM64Reg)(inst & 0x1F); + } + else // 64-bit float + { + // Real register is in the INS instruction + u32 ins_inst = *(u32*)(ptr + 8); + *reg = (ARM64Reg)(ins_inst & 0x1F); } *flags |= BackPatchInfo::FLAG_LOAD; - *reg = (ARM64Reg)(inst & 0x1F); return true; } else if (op == 0xF4) // NEON STR @@ -74,9 +83,17 @@ bool JitArm64::DisasmLoadStore(const u8* ptr, u32* flags, ARM64Reg* reg) { *flags &= ~BackPatchInfo::FLAG_SIZE_32; *flags |= BackPatchInfo::FLAG_SIZE_F32; + + // Real register is in the first FCVT conversion instruction + u32 fcvt_inst = *(u32*)(ptr - 8); + *reg = (ARM64Reg)((fcvt_inst >> 5) & 0x1F); + } + else // 64-bit float + { + // Real register is in the previous REV64 instruction + *reg = (ARM64Reg)((prev_inst >> 5) & 0x1F); } *flags |= BackPatchInfo::FLAG_STORE; - *reg = (ARM64Reg)(inst & 0x1F); return true; } else if (op == 0xE5) // Load @@ -200,14 +217,14 @@ u32 JitArm64::EmitBackpatchRoutine(ARM64XEmitter* emit, u32 flags, bool fastmem, if (flags & BackPatchInfo::FLAG_SIZE_F32) { float_emit.FCVT(32, 64, Q0, RS); - float_emit.FMOV(32, false, W0, Q0); + float_emit.UMOV(32, W0, Q0, 0); emit->MOVI2R(X30, (u64)&Memory::Write_U32); emit->BLR(X30); } else { - emit->MOVI2R(X30, (u64)&Memory::Write_F64); - float_emit.DUP(64, Q0, RS); + emit->MOVI2R(X30, (u64)&Memory::Write_U64); + float_emit.UMOV(64, X0, RS, 0); emit->BLR(X30); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp index 38d3b4b8fe..e8cb2502bb 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp @@ -260,11 +260,7 @@ void JitArm64::stfXX(UGeckoInstruction inst) bool is_immediate = false; ARM64Reg V0 = fpr.R(inst.FS); - ARM64Reg addr_reg; - if (flags & BackPatchInfo::FLAG_SIZE_F64) - addr_reg = W0; - else - addr_reg = W1; + ARM64Reg addr_reg = W1; gpr.Lock(W0, W1, W30); fpr.Lock(Q0);