[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.
This commit is contained in:
Ryan Houdek 2015-01-20 19:11:04 -06:00
parent 7f68a357ad
commit 32bfccce32
2 changed files with 23 additions and 10 deletions

View File

@ -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);
}

View File

@ -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);