Core: clear FPU StatusReg cause in CX86RecompilerOps::COP1_S_ADD

This commit is contained in:
zilmar 2023-05-02 11:12:13 +09:30
parent 02a48566c0
commit fa25b6d2af
3 changed files with 41 additions and 3 deletions

View File

@ -2434,7 +2434,7 @@ void CX86RecompilerOps::SLTIU()
if (m_RegWorkingSet.IsConst(m_Opcode.rs))
{
uint32_t Result = m_RegWorkingSet.Is64Bit(m_Opcode.rs) ? m_RegWorkingSet.GetMipsReg(m_Opcode.rs) < ((unsigned)((int64_t)((int16_t)m_Opcode.immediate))) ? 1 : 0 : m_RegWorkingSet.GetMipsRegLo(m_Opcode.rs) < ((unsigned)((int16_t)m_Opcode.immediate)) ? 1
: 0;
: 0;
m_RegWorkingSet.UnMap_GPR(m_Opcode.rt, false);
m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN);
m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, Result);
@ -6952,7 +6952,7 @@ void CX86RecompilerOps::SPECIAL_DSUBU()
m_RegWorkingSet.SetMipsReg(m_Opcode.rd,
m_RegWorkingSet.Is64Bit(m_Opcode.rs) ? m_RegWorkingSet.GetMipsReg(m_Opcode.rs) : (int64_t)m_RegWorkingSet.GetMipsRegLo_S(m_Opcode.rs) - m_RegWorkingSet.Is64Bit(m_Opcode.rt) ? m_RegWorkingSet.GetMipsReg(m_Opcode.rt)
: (int64_t)m_RegWorkingSet.GetMipsRegLo_S(m_Opcode.rt));
: (int64_t)m_RegWorkingSet.GetMipsRegLo_S(m_Opcode.rt));
if (m_RegWorkingSet.GetMipsRegLo_S(m_Opcode.rd) < 0 && m_RegWorkingSet.GetMipsRegHi_S(m_Opcode.rd) == -1)
{
m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN);
@ -7599,6 +7599,8 @@ void CX86RecompilerOps::COP1_S_ADD()
CompileCop1Test();
m_RegWorkingSet.FixRoundModel(CRegInfo::RoundDefault);
asmjit::x86::Gp StatusReg = m_RegWorkingSet.Map_FPStatusReg();
m_Assembler.and_(StatusReg, (uint32_t)(~0x0003F000));
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float);
if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Float))
{
@ -7612,7 +7614,7 @@ void CX86RecompilerOps::COP1_S_ADD()
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float);
m_Assembler.fadd(asmjit::x86::dword_ptr(TempReg));
}
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
m_RegWorkingSet.UnMap_X86reg(StatusReg);
}
void CX86RecompilerOps::COP1_S_SUB()

View File

@ -734,6 +734,29 @@ asmjit::x86::Gp CX86RegInfo::UnMap_8BitTempReg()
return x86Reg_Unknown;
}
asmjit::x86::Gp CX86RegInfo::Map_FPStatusReg()
{
for (int32_t i = 0, n = x86RegIndex_Size; i < n; i++)
{
if (GetX86Mapped((x86RegIndex)i) == FPStatusReg_Mapped)
{
return GetX86RegFromIndex((x86RegIndex)i);
}
}
asmjit::x86::Gp Reg = FreeX86Reg();
if (!Reg.isValid())
{
g_Notify->DisplayError("Map_MemoryStack\n\nOut of registers");
g_Notify->BreakPoint(__FILE__, __LINE__);
return Reg;
}
SetX86Mapped(GetIndexFromX86Reg(Reg), CX86RegInfo::FPStatusReg_Mapped);
m_CodeBlock.Log(" regcache: allocate %s as FP Status Reg", CX86Ops::x86_Name(Reg));
m_Assembler.MoveVariableToX86reg(Reg, &g_Reg->m_FPCR[31], "FPCR[31]");
return Reg;
}
asmjit::x86::Gp CX86RegInfo::Get_MemoryStack() const
{
for (int32_t i = 0, n = x86RegIndex_Size; i < n; i++)
@ -1570,6 +1593,17 @@ bool CX86RegInfo::UnMap_X86reg(const asmjit::x86::Gp & Reg)
SetX86Mapped(RegIndex, NotMapped);
return true;
}
else if (GetX86Mapped(RegIndex) == CX86RegInfo::FPStatusReg_Mapped)
{
m_CodeBlock.Log(" regcache: unallocate %s from FP Status Reg", CX86Ops::x86_Name(Reg));
m_Assembler.MoveX86regToVariable(&g_Reg->m_FPCR[31], "FPCR[31]", Reg);
SetX86Mapped(RegIndex, NotMapped);
return true;
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
return false;
}

View File

@ -52,6 +52,7 @@ public:
GPR_Mapped = 1,
Temp_Mapped = 2,
Stack_Mapped = 3,
FPStatusReg_Mapped = 4,
};
enum FPU_STATE
@ -90,6 +91,7 @@ public:
asmjit::x86::Gp Free8BitX86Reg();
void Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsRegToLoad);
void Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad);
asmjit::x86::Gp Map_FPStatusReg();
asmjit::x86::Gp Get_MemoryStack() const;
asmjit::x86::Gp Map_MemoryStack(asmjit::x86::Gp Reg, bool bMapRegister, bool LoadValue = true);
asmjit::x86::Gp Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, bool LoadHiWord, bool Reg8Bit);