Core: Clean up arm recompiler changes

This commit is contained in:
zilmar 2022-09-12 22:44:42 +09:30
parent 457937f039
commit a79a8a9276
11 changed files with 1614 additions and 1553 deletions

View File

@ -366,7 +366,6 @@ void CMipsMemoryVM::DumpArmExceptionInfo(uint32_t MemAddress, mcontext_t & conte
{
WriteTrace(TraceExceptionHandler, TraceError, "GPR[%s] 0x%08X%08X", CRegName::GPR[count], g_Reg->m_GPR[count].W[1], g_Reg->m_GPR[count].W[0]);
}
Flush_Recompiler_Log();
TraceFlushLog();
}

View File

@ -2,32 +2,37 @@
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Recompiler/RecompilerCodeLog.h>
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmOps.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmOpCode.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h>
#include <Project64-core/N64System/Recompiler/CodeBlock.h>
CArmRegInfo CArmOps::m_RegWorkingSet;
bool CArmOps::m_InItBlock = false;
int CArmOps::m_ItBlockInstruction = 0;
CArmOps::ArmCompareType CArmOps::m_ItBlockCompareType;
CArmOps::ArmItMask CArmOps::m_ItBlockMask;
CArmOps::ArmReg CArmOps::m_LastStoreReg;
uint16_t CArmOps::m_PopRegisters = 0;
uint16_t CArmOps::m_PushRegisters = 0;
CArmOps::CArmOps(CCodeBlock & CodeBlock, CArmRegInfo & RegWorkingSet) :
m_CodeBlock(CodeBlock),
m_RegWorkingSet(RegWorkingSet),
m_InItBlock(false),
m_ItBlockInstruction(0),
m_ItBlockCompareType(ArmBranch_Equal),
m_ItBlockMask(ItMask_None),
m_LastStoreReg(CArmOps::Arm_Unknown),
m_PopRegisters(0),
m_PushRegisters(0)
{
}
// Logging functions
void CArmOps::WriteArmComment(const char * Comment)
{
CPU_Message("");
CPU_Message(" // %s", Comment);
CodeLog("");
CodeLog(" // %s", Comment);
}
void CArmOps::WriteArmLabel(const char * Label)
{
CPU_Message("");
CPU_Message(" %s:", Label);
CodeLog("");
CodeLog(" %s:", Label);
}
void CArmOps::AddArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2)
@ -36,7 +41,7 @@ void CArmOps::AddArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Source
if (DestReg <= 7 && SourceReg1 <= 7 && SourceReg2 <= 7)
{
CPU_Message(" add\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
CodeLog(" add\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
ArmThumbOpcode op = { 0 };
op.Reg.rt = DestReg;
op.Reg.rn = SourceReg1;
@ -46,7 +51,7 @@ void CArmOps::AddArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Source
}
else
{
CPU_Message(" add.w\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
CodeLog(" add.w\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
Arm32Opcode op = { 0 };
op.imm5.rn = SourceReg1;
op.imm5.s = 0;
@ -75,7 +80,7 @@ void CArmOps::AndConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const)
if (CanThumbCompressConst(Const))
{
CPU_Message(" and\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
CodeLog(" and\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
uint16_t CompressedConst = ThumbCompressConst(Const);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = SourceReg;
@ -129,7 +134,7 @@ void CArmOps::AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const)
}
else if ((Const & 0xFFFFFFF8) == 0 && DestReg <= 7 && SourceReg <= 7)
{
CPU_Message(" adds\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
CodeLog(" adds\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
ArmThumbOpcode op = { 0 };
op.Imm3.rd = DestReg;
op.Imm3.rn = SourceReg;
@ -139,7 +144,7 @@ void CArmOps::AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const)
}
else if ((Const & 0xFFFFFF00) == 0 && DestReg <= 7 && DestReg == SourceReg)
{
CPU_Message(" adds\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
CodeLog(" adds\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
ArmThumbOpcode op = { 0 };
op.Imm8.imm8 = Const;
op.Imm8.rdn = DestReg;
@ -148,7 +153,7 @@ void CArmOps::AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const)
}
else if ((Const & 0xFFFFFF80) == 0xFFFFFF80 && DestReg <= 7 && DestReg == SourceReg)
{
CPU_Message(" sub\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (~Const) + 1);
CodeLog(" sub\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (~Const) + 1);
ArmThumbOpcode op = { 0 };
op.Imm8.imm8 = ((~Const) + 1) & 0xFF;
op.Imm8.rdn = DestReg;
@ -157,7 +162,7 @@ void CArmOps::AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const)
}
else if (CanThumbCompressConst(Const))
{
CPU_Message(" add.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
CodeLog(" add.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
uint16_t CompressedConst = ThumbCompressConst(Const);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = SourceReg;
@ -181,7 +186,7 @@ void CArmOps::AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const)
}
else
{
CPU_Message("%s: DestReg = %X Const = %X", __FUNCTION__, DestReg, Const);
CodeLog("%s: DestReg = %X Const = %X", __FUNCTION__, DestReg, Const);
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
@ -192,7 +197,7 @@ void CArmOps::AndArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Source
if (DestReg <= 0x7 && SourceReg2 <= 0x7 && SourceReg1 == DestReg)
{
CPU_Message(" ands\t%s, %s", ArmRegName(DestReg), ArmRegName(SourceReg2));
CodeLog(" ands\t%s, %s", ArmRegName(DestReg), ArmRegName(SourceReg2));
ArmThumbOpcode op = { 0 };
op.Reg2.rn = DestReg;
op.Reg2.rm = SourceReg2;
@ -201,7 +206,7 @@ void CArmOps::AndArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Source
}
else
{
CPU_Message(" and.w\t%s, %s, %s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
CodeLog(" and.w\t%s, %s, %s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
Arm32Opcode op = { 0 };
op.imm5.rn = SourceReg1;
op.imm5.s = 0;
@ -223,7 +228,7 @@ void CArmOps::ArmBreakPoint(const char * FileName, uint32_t LineNumber)
m_RegWorkingSet.BeforeCallDirect();
MoveConstToArmReg(Arm_R1, LineNumber);
MoveConstToArmReg(Arm_R0, (uint32_t)FileName, FileName);
CallFunction(AddressOf(&BreakPointNotification), "BreakPointNotification");
CallFunction(AddressOf(&CArmOps::BreakPointNotification), "BreakPointNotification");
m_RegWorkingSet.AfterCallDirect();
}
@ -231,7 +236,7 @@ void CArmOps::ArmNop(void)
{
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
CPU_Message(" nop");
CodeLog(" nop");
AddCode16(0xbf00);
}
@ -239,7 +244,7 @@ void CArmOps::BranchLabel8(ArmCompareType CompareType, const char * Label)
{
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
CPU_Message(" b%s\t%s", ArmCompareSuffix(CompareType), Label);
CodeLog(" b%s\t%s", ArmCompareSuffix(CompareType), Label);
ArmThumbOpcode op = { 0 };
if (CompareType == ArmBranch_Always)
{
@ -259,7 +264,7 @@ void CArmOps::BranchLabel20(ArmCompareType CompareType, const char * Label)
{
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
CPU_Message(" b%s\t%s", ArmCompareSuffix(CompareType), Label);
CodeLog(" b%s\t%s", ArmCompareSuffix(CompareType), Label);
Arm32Opcode op = { 0 };
op.Branch20.imm6 = 0;
op.Branch20.cond = CompareType == ArmBranch_Always ? 0 : CompareType;
@ -284,7 +289,7 @@ void CArmOps::CallFunction(void * Function, const char * FunctionName)
op.Branch.reserved = 0;
op.Branch.rm = reg;
op.Branch.opcode = 0x8F;
CPU_Message(" blx\t%s", ArmRegName(reg));
CodeLog(" blx\t%s", ArmRegName(reg));
AddCode16(op.Hex);
}
@ -317,7 +322,7 @@ void CArmOps::MoveConstToArmReg(ArmReg Reg, uint16_t value, const char * comment
PreOpCheck(Arm_Unknown, true, __FILE__, __LINE__);
if ((value & 0xFF00) == 0 && Reg <= 7)
{
CPU_Message(" mov%s\t%s, #0x%X\t; %s", m_InItBlock ? ArmCurrentItCondition() : "s", ArmRegName(Reg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
CodeLog(" mov%s\t%s, #0x%X\t; %s", m_InItBlock ? ArmCurrentItCondition() : "s", ArmRegName(Reg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
ArmThumbOpcode op = { 0 };
op.Imm8.imm8 = value;
op.Imm8.rdn = Reg;
@ -326,7 +331,7 @@ void CArmOps::MoveConstToArmReg(ArmReg Reg, uint16_t value, const char * comment
}
else if (CanThumbCompressConst(value))
{
CPU_Message(" mov%s.w\t%s, #0x%X\t; %s", m_InItBlock ? ArmCurrentItCondition() : "", ArmRegName(Reg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
CodeLog(" mov%s.w\t%s, #0x%X\t; %s", m_InItBlock ? ArmCurrentItCondition() : "", ArmRegName(Reg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
uint16_t CompressedValue = ThumbCompressConst(value);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = 0xF;
@ -343,7 +348,7 @@ void CArmOps::MoveConstToArmReg(ArmReg Reg, uint16_t value, const char * comment
}
else
{
CPU_Message(" movw%s\t%s, #0x%X\t; %s", m_InItBlock ? ArmCurrentItCondition() : "", ArmRegName(Reg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
CodeLog(" movw%s\t%s, #0x%X\t; %s", m_InItBlock ? ArmCurrentItCondition() : "", ArmRegName(Reg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
Arm32Opcode op = { 0 };
op.imm16.opcode = ArmMOV_IMM16;
@ -367,7 +372,7 @@ void CArmOps::MoveConstToArmRegTop(ArmReg DestReg, uint16_t Const, const char *
{
PreOpCheck(DestReg, false, __FILE__, __LINE__);
CPU_Message(" movt\t%s, %s", ArmRegName(DestReg), comment != nullptr ? stdstr_f("#0x%X\t; %s", (uint32_t)Const, comment).c_str() : stdstr_f("#%d\t; 0x%X", (uint32_t)Const, (uint32_t)Const).c_str());
CodeLog(" movt\t%s, %s", ArmRegName(DestReg), comment != nullptr ? stdstr_f("#0x%X\t; %s", (uint32_t)Const, comment).c_str() : stdstr_f("#%d\t; 0x%X", (uint32_t)Const, (uint32_t)Const).c_str());
Arm32Opcode op = { 0 };
op.imm16.opcode = ArmMOV_IMM16;
@ -391,7 +396,7 @@ void CArmOps::CompareArmRegToConst(ArmReg Reg, uint32_t value)
if (Reg <= 0x7 && (value & 0xFFFFFF00) == 0)
{
CPU_Message(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value);
CodeLog(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value);
ArmThumbOpcode op = { 0 };
op.Imm8.imm8 = value;
op.Imm8.rdn = Reg;
@ -400,7 +405,7 @@ void CArmOps::CompareArmRegToConst(ArmReg Reg, uint32_t value)
}
else if (CanThumbCompressConst(value))
{
CPU_Message(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value);
CodeLog(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value);
uint16_t CompressedValue = ThumbCompressConst(value);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = Reg;
@ -430,7 +435,7 @@ void CArmOps::CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2)
if (Reg1 <= 0x7 && Reg2 <= 0x7)
{
CPU_Message(" cmp\t%s, %s", ArmRegName(Reg1), ArmRegName(Reg2));
CodeLog(" cmp\t%s, %s", ArmRegName(Reg1), ArmRegName(Reg2));
ArmThumbOpcode op = { 0 };
op.Reg2.rn = Reg1;
op.Reg2.rm = Reg2;
@ -439,7 +444,7 @@ void CArmOps::CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2)
}
else
{
CPU_Message(" cmp.w\t%s, %s", ArmRegName(Reg1), ArmRegName(Reg2));
CodeLog(" cmp.w\t%s, %s", ArmRegName(Reg1), ArmRegName(Reg2));
Arm32Opcode op = { 0 };
op.imm5.rn = Reg1;
op.imm5.s = 1;
@ -460,7 +465,7 @@ void CArmOps::IfBlock(ArmItMask mask, ArmCompareType CompareType)
{
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
CPU_Message(" it%s\t%s", ArmItMaskName(mask), ArmCompareSuffix(CompareType));
CodeLog(" it%s\t%s", ArmItMaskName(mask), ArmCompareSuffix(CompareType));
m_InItBlock = true;
m_ItBlockInstruction = 0;
m_ItBlockCompareType = CompareType;
@ -490,11 +495,11 @@ void CArmOps::LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, u
{
if ((offset & (~0xFFF)) != 0)
{
CPU_Message(" RegPointer: %d Reg: %d Offset: 0x%X", RegPointer, DestReg, offset);
CodeLog(" RegPointer: %d Reg: %d Offset: 0x%X", RegPointer, DestReg, offset);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CPU_Message(" ldrb.w\t%s, [%s, #%d]", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)offset);
CodeLog(" ldrb.w\t%s, [%s, #%d]", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)offset);
Arm32Opcode op = { 0 };
op.imm12.rt = DestReg;
op.imm12.rn = RegPointer;
@ -504,7 +509,7 @@ void CArmOps::LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, u
}
else
{
CPU_Message(" ldrb\t%s, [%s%s%s]", ArmRegName(DestReg), ArmRegName(RegPointer), offset == 0 ? "" : ",", offset == 0 ? "" : stdstr_f("#%d", offset).c_str());
CodeLog(" ldrb\t%s, [%s%s%s]", ArmRegName(DestReg), ArmRegName(RegPointer), offset == 0 ? "" : ",", offset == 0 ? "" : stdstr_f("#%d", offset).c_str());
ArmThumbOpcode op = { 0 };
op.Imm5.rt = DestReg;
op.Imm5.rn = RegPointer;
@ -520,7 +525,7 @@ void CArmOps::LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, A
if ((DestReg > 0x7 || RegPointer > 0x7 || RegPointer2 > 0x7) && (shift & ~3) == 0)
{
CPU_Message(" ldrb\t%s, [%s,%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
CodeLog(" ldrb\t%s, [%s,%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
Arm32Opcode op = { 0 };
op.uint16.rn = RegPointer;
op.uint16.opcode = 0xF81;
@ -532,7 +537,7 @@ void CArmOps::LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, A
}
else if (shift == 0 && DestReg <= 0x7 && RegPointer <= 0x7 && RegPointer2 <= 0x7)
{
CPU_Message(" ldrb\t%s, [%s,%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
CodeLog(" ldrb\t%s, [%s,%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
ArmThumbOpcode op = { 0 };
op.Reg.rm = RegPointer2;
op.Reg.rt = DestReg;
@ -554,11 +559,11 @@ void CArmOps::LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, uint8
{
if ((Offset & (~0xFFF)) != 0)
{
CPU_Message(" RegPointer: %d Reg: %d Offset: 0x%X", RegPointer, DestReg, Offset);
CodeLog(" RegPointer: %d Reg: %d Offset: 0x%X", RegPointer, DestReg, Offset);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CPU_Message(" ldr.w\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
CodeLog(" ldr.w\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
Arm32Opcode op = { 0 };
op.imm12.rt = DestReg;
op.imm12.rn = RegPointer;
@ -568,7 +573,7 @@ void CArmOps::LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, uint8
}
else
{
CPU_Message(" ldr\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
CodeLog(" ldr\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
ArmThumbOpcode op = { 0 };
op.Imm5.rt = DestReg;
op.Imm5.rn = RegPointer;
@ -590,7 +595,7 @@ void CArmOps::LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, ArmRe
if (shift == 0 && DestReg <= 0x7 && RegPointer <= 0x7 && RegPointer2 <= 0x7)
{
CPU_Message(" ldr\t%s, [%s,%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
CodeLog(" ldr\t%s, [%s,%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
ArmThumbOpcode op = { 0 };
op.Reg.rm = RegPointer2;
op.Reg.rt = DestReg;
@ -600,7 +605,7 @@ void CArmOps::LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, ArmRe
}
else
{
CPU_Message(" ldr.w\t%s, [%s, %s, lsl #%d]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2), shift);
CodeLog(" ldr.w\t%s, [%s, %s, lsl #%d]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2), shift);
Arm32Opcode op = { 0 };
op.imm2.rm = RegPointer2;
op.imm2.imm = shift;
@ -618,11 +623,11 @@ void CArmOps::LoadArmRegPointerToFloatReg(ArmReg RegPointer, ArmFpuSingle Reg, u
if (Offset != 0)
{
CPU_Message(" vldr\t%s, [%s, #%d]", ArmFpuSingleName(Reg), ArmRegName(RegPointer), (uint32_t)Offset);
CodeLog(" vldr\t%s, [%s, #%d]", ArmFpuSingleName(Reg), ArmRegName(RegPointer), (uint32_t)Offset);
}
else
{
CPU_Message(" vldr\t%s, [%s]", ArmFpuSingleName(Reg), ArmRegName(RegPointer));
CodeLog(" vldr\t%s, [%s]", ArmFpuSingleName(Reg), ArmRegName(RegPointer));
}
Arm32Opcode op = { 0 };
op.RnVdImm8.Rn = RegPointer;
@ -648,7 +653,7 @@ void CArmOps::LoadFloatingPointControlReg(ArmReg DestReg)
{
PreOpCheck(DestReg, false, __FILE__, __LINE__);
CPU_Message(" vmrs\t%s, fpscr", ArmRegName(DestReg));
CodeLog(" vmrs\t%s, fpscr", ArmRegName(DestReg));
Arm32Opcode op = { 0 };
op.fpscr.opcode2 = 0xA10;
op.fpscr.rt = DestReg;
@ -662,7 +667,7 @@ void CArmOps::MoveConstToArmReg(ArmReg DestReg, uint32_t value, const char * com
{
PreOpCheck(DestReg, false, __FILE__, __LINE__);
CPU_Message(" mov.w\t%s, #0x%X\t; %s", ArmRegName(DestReg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
CodeLog(" mov.w\t%s, #0x%X\t; %s", ArmRegName(DestReg), (uint32_t)value, comment != nullptr ? comment : stdstr_f("0x%X", (uint32_t)value).c_str());
uint16_t CompressedValue = ThumbCompressConst(value);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = 0xF;
@ -734,7 +739,7 @@ void CArmOps::OrArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceR
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CPU_Message(" orr.w\t%s, %s, %s%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2), shift ? stdstr_f(", lsl #%d", shift).c_str() : "");
CodeLog(" orr.w\t%s, %s, %s%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2), shift ? stdstr_f(", lsl #%d", shift).c_str() : "");
Arm32Opcode op = { 0 };
op.imm5.rn = SourceReg1;
op.imm5.s = 0;
@ -762,7 +767,7 @@ void CArmOps::OrConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t value)
else if (CanThumbCompressConst(value))
{
uint16_t CompressedValue = ThumbCompressConst(value);
CPU_Message(" orr\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), value);
CodeLog(" orr\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), value);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = SourceReg;
op.imm8_3_1.s = 0;
@ -810,7 +815,7 @@ void CArmOps::MulF32(ArmFpuSingle DestReg, ArmFpuSingle SourceReg1, ArmFpuSingle
{
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
CPU_Message(" vmul.f32\t%s, %s, %s", ArmFpuSingleName(DestReg), ArmFpuSingleName(SourceReg1), ArmFpuSingleName(SourceReg2));
CodeLog(" vmul.f32\t%s, %s, %s", ArmFpuSingleName(DestReg), ArmFpuSingleName(SourceReg1), ArmFpuSingleName(SourceReg2));
Arm32Opcode op = { 0 };
op.VnVmVd.vn = SourceReg1 >> 1;
op.VnVmVd.op1 = 0x2;
@ -835,7 +840,7 @@ void CArmOps::PushArmReg(uint16_t Registers)
{
if (Registers == m_PopRegisters)
{
CPU_Message("%s: Ignoring push/pop", __FUNCTION__);
CodeLog("%s: Ignoring push/pop", __FUNCTION__);
m_PopRegisters = 0;
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
return;
@ -872,7 +877,7 @@ void CArmOps::PushArmReg(uint16_t Registers)
(Registers & ArmPushPop_R11) != 0 ||
(Registers & ArmPushPop_R12) != 0)
{
CPU_Message("%X: push\t{%s}", (int32_t)*g_RecompPos, pushed.c_str());
CodeLog("%X: push\t{%s}", (int32_t)*g_RecompPos, pushed.c_str());
Arm32Opcode op = { 0 };
op.PushPop.register_list = Registers;
@ -881,7 +886,7 @@ void CArmOps::PushArmReg(uint16_t Registers)
}
else
{
CPU_Message(" push\t%s", pushed.c_str());
CodeLog(" push\t%s", pushed.c_str());
bool lr = (Registers & ArmPushPop_LR) != 0;
Registers &= Registers & ~ArmPushPop_LR;
@ -905,12 +910,12 @@ void CArmOps::PopArmReg(uint16_t Registers)
}
if (m_PushRegisters == 0 && (Registers & ArmPushPop_PC) == 0)
{
CPU_Message("%s: Setting m_PushRegisters: %X Registers: %X", __FUNCTION__, m_PushRegisters, Registers);
CodeLog("%s: Setting m_PushRegisters: %X Registers: %X", __FUNCTION__, m_PushRegisters, Registers);
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (m_PushRegisters != Registers && (Registers & ArmPushPop_PC) == 0)
{
CPU_Message("%s: Setting m_PushRegisters: %X Registers: %X", __FUNCTION__, m_PushRegisters, Registers);
CodeLog("%s: Setting m_PushRegisters: %X Registers: %X", __FUNCTION__, m_PushRegisters, Registers);
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if ((Registers & ArmPushPop_SP) != 0) { g_Notify->BreakPoint(__FILE__, __LINE__); }
@ -942,7 +947,7 @@ void CArmOps::FlushPopArmReg(void)
(m_PopRegisters & ArmPushPop_R11) != 0 ||
(m_PopRegisters & ArmPushPop_R12) != 0)
{
CPU_Message("%X pop\t{%s}", (int32_t)*g_RecompPos, pushed.c_str());
CodeLog("%X pop\t{%s}", (int32_t)*g_RecompPos, pushed.c_str());
Arm32Opcode op = { 0 };
op.PushPop.register_list = m_PopRegisters;
@ -951,7 +956,7 @@ void CArmOps::FlushPopArmReg(void)
}
else
{
CPU_Message(" pop\t%s", pushed.c_str());
CodeLog(" pop\t%s", pushed.c_str());
bool pc = (m_PopRegisters & ArmPushPop_PC) != 0;
m_PopRegisters &= ~ArmPushPop_PC;
@ -1021,7 +1026,7 @@ void CArmOps::ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shi
}
else if (DestReg > 0x7 || SourceReg > 0x7)
{
CPU_Message(" asrs.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
CodeLog(" asrs.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
Arm32Opcode op = { 0 };
op.imm5.rn = 0xF;
op.imm5.s = 0;
@ -1037,7 +1042,7 @@ void CArmOps::ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shi
}
else
{
CPU_Message(" asrs\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
CodeLog(" asrs\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
ArmThumbOpcode op = { 0 };
op.Imm5.rt = DestReg;
@ -1058,7 +1063,7 @@ void CArmOps::ShiftRightUnsignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t s
}
if (DestReg > 0x7 || SourceReg > 0x7)
{
CPU_Message(" lsrs.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
CodeLog(" lsrs.w\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
Arm32Opcode op = { 0 };
op.imm5.rn = 0xF;
op.imm5.s = 0;
@ -1074,7 +1079,7 @@ void CArmOps::ShiftRightUnsignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t s
}
else
{
CPU_Message(" lsrs\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
CodeLog(" lsrs\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
ArmThumbOpcode op = { 0 };
op.Imm5.rt = DestReg;
@ -1094,7 +1099,7 @@ void CArmOps::ShiftLeftImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift)
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CPU_Message(" lsls\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
CodeLog(" lsls\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(SourceReg), (uint32_t)shift);
ArmThumbOpcode op = { 0 };
op.Imm5.rt = DestReg;
@ -1108,7 +1113,7 @@ void CArmOps::SignExtendByte(ArmReg Reg)
{
if (Reg > 0x7)
{
CPU_Message(" sxtb.w\t%s, %s", ArmRegName(Reg), ArmRegName(Reg));
CodeLog(" sxtb.w\t%s, %s", ArmRegName(Reg), ArmRegName(Reg));
Arm32Opcode op = { 0 };
op.rotate.opcode = 0xFA4F;
op.rotate.rm = Reg;
@ -1120,7 +1125,7 @@ void CArmOps::SignExtendByte(ArmReg Reg)
}
else
{
CPU_Message(" sxtb\t%s, %s", ArmRegName(Reg), ArmRegName(Reg));
CodeLog(" sxtb\t%s, %s", ArmRegName(Reg), ArmRegName(Reg));
ArmThumbOpcode op = { 0 };
op.Reg2.rn = Reg;
op.Reg2.rm = Reg;
@ -1137,7 +1142,7 @@ void CArmOps::StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, uint
{
if ((Offset & (~0xFFF)) != 0) { g_Notify->BreakPoint(__FILE__, __LINE__); return; }
CPU_Message(" str\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
CodeLog(" str\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
Arm32Opcode op = { 0 };
op.imm12.rt = DestReg;
op.imm12.rn = RegPointer;
@ -1147,7 +1152,7 @@ void CArmOps::StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, uint
}
else
{
CPU_Message(" str\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
CodeLog(" str\t%s, [%s, #%d]%s%s", ArmRegName(DestReg), ArmRegName(RegPointer), (uint32_t)Offset, comment != nullptr ? "\t; " : "", comment != nullptr ? comment : "");
ArmThumbOpcode op = { 0 };
op.Imm5.rt = DestReg;
op.Imm5.rn = RegPointer;
@ -1164,7 +1169,7 @@ void CArmOps::StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, ArmR
if (DestReg > 0x7 || RegPointer > 0x7 || RegPointer2 > 0x7 || shift != 0)
{
CPU_Message(" str.w\t%s, [%s, %s%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2), shift != 0 ? stdstr_f(", lsl #%d", shift).c_str() : "");
CodeLog(" str.w\t%s, [%s, %s%s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2), shift != 0 ? stdstr_f(", lsl #%d", shift).c_str() : "");
Arm32Opcode op = { 0 };
op.imm2.rm = RegPointer2;
op.imm2.imm = shift;
@ -1176,7 +1181,7 @@ void CArmOps::StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, ArmR
}
else
{
CPU_Message(" str\t%s, [%s, %s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
CodeLog(" str\t%s, [%s, %s]", ArmRegName(DestReg), ArmRegName(RegPointer), ArmRegName(RegPointer2));
ArmThumbOpcode op = { 0 };
op.Reg.rt = DestReg;
op.Reg.rn = RegPointer;
@ -1190,7 +1195,7 @@ void CArmOps::StoreFloatingPointControlReg(ArmReg SourceReg)
{
PreOpCheck(Arm_Unknown, false, __FILE__, __LINE__);
CPU_Message(" vmsr\tfpscr, %s", ArmRegName(SourceReg));
CodeLog(" vmsr\tfpscr, %s", ArmRegName(SourceReg));
Arm32Opcode op = { 0 };
op.fpscr.opcode2 = 0xA10;
op.fpscr.rt = SourceReg;
@ -1204,11 +1209,11 @@ void CArmOps::StoreFloatRegToArmRegPointer(ArmFpuSingle Reg, ArmReg RegPointer,
if (Offset != 0)
{
CPU_Message(" vstr\t%s, [%s, #%d]", ArmFpuSingleName(Reg), ArmRegName(RegPointer), (uint32_t)Offset);
CodeLog(" vstr\t%s, [%s, #%d]", ArmFpuSingleName(Reg), ArmRegName(RegPointer), (uint32_t)Offset);
}
else
{
CPU_Message(" vstr\t%s, [%s]", ArmFpuSingleName(Reg), ArmRegName(RegPointer));
CodeLog(" vstr\t%s, [%s]", ArmFpuSingleName(Reg), ArmRegName(RegPointer));
}
Arm32Opcode op = { 0 };
op.RnVdImm8.Rn = RegPointer;
@ -1229,7 +1234,7 @@ void CArmOps::SubArmRegFromArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Sour
if (DestReg <= 7 && SourceReg1 <= 7 && SourceReg2 <= 7)
{
CPU_Message(" subs\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
CodeLog(" subs\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
ArmThumbOpcode op = { 0 };
op.Reg.rt = DestReg;
op.Reg.rn = SourceReg1;
@ -1239,7 +1244,7 @@ void CArmOps::SubArmRegFromArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Sour
}
else
{
CPU_Message(" sub.w\t%s, %s, %s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
CodeLog(" sub.w\t%s, %s, %s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
Arm32Opcode op = { 0 };
op.imm5.rn = SourceReg1;
op.imm5.s = 0;
@ -1261,7 +1266,7 @@ void CArmOps::SubConstFromArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Cons
if (DestReg <= 7 && DestReg == SourceReg && (Const & (~0xFF)) == 0)
{
CPU_Message(" subs\t%s, #0x%X", ArmRegName(DestReg), Const);
CodeLog(" subs\t%s, #0x%X", ArmRegName(DestReg), Const);
ArmThumbOpcode op = { 0 };
op.Imm8.imm8 = (uint8_t)Const;
op.Imm8.rdn = DestReg;
@ -1270,7 +1275,7 @@ void CArmOps::SubConstFromArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Cons
}
else if ((Const & (~0x7FF)) == 0)
{
CPU_Message(" sub.w\t%s, %s, #0x%X", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
CodeLog(" sub.w\t%s, %s, #0x%X", ArmRegName(DestReg), ArmRegName(SourceReg), Const);
Arm32Opcode op = { 0 };
op.RnRdImm12.Rn = SourceReg;
op.RnRdImm12.s = 0;
@ -1334,7 +1339,7 @@ void CArmOps::XorArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg)
if (SourceReg <= 7 && DestReg <= 7)
{
CPU_Message(" eors\t%s, %s", ArmRegName(DestReg), ArmRegName(SourceReg));
CodeLog(" eors\t%s, %s", ArmRegName(DestReg), ArmRegName(SourceReg));
ArmThumbOpcode op = { 0 };
op.Reg2.rn = DestReg;
op.Reg2.rm = SourceReg;
@ -1351,7 +1356,7 @@ void CArmOps::XorArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg Source
{
PreOpCheck(DestReg, false, __FILE__, __LINE__);
CPU_Message(" eor.w\t%s, %s, %s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
CodeLog(" eor.w\t%s, %s, %s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
Arm32Opcode op = { 0 };
op.imm5.rn = SourceReg1;
op.imm5.s = 0;
@ -1377,7 +1382,7 @@ void CArmOps::XorConstToArmReg(ArmReg DestReg, uint32_t value)
else if (CanThumbCompressConst(value))
{
uint16_t CompressedValue = ThumbCompressConst(value);
CPU_Message(" eor\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(DestReg), value);
CodeLog(" eor\t%s, %s, #%d", ArmRegName(DestReg), ArmRegName(DestReg), value);
Arm32Opcode op = { 0 };
op.imm8_3_1.rn = DestReg;
op.imm8_3_1.s = 0;
@ -1465,8 +1470,8 @@ uint16_t CArmOps::ThumbCompressConst(uint32_t value)
return (uint16_t)(0x300 | (value & 0xFF));
}
CPU_Message("%s: value >> 24 = %X value >> 16 = %X value >> 8 = %X value = %X", __FUNCTION__, (value >> 24), (value >> 16), (value >> 8), value);
CPU_Message("%s: value = %X", __FUNCTION__, value);
CodeLog("%s: value >> 24 = %X value >> 16 = %X value >> 8 = %X value = %X", __FUNCTION__, (value >> 24), (value >> 16), (value >> 8), value);
CodeLog("%s: value = %X", __FUNCTION__, value);
g_Notify->BreakPoint(__FILE__, __LINE__);
return false;
}
@ -1497,8 +1502,8 @@ void CArmOps::SetJump8(uint8_t * Loc, uint8_t * JumpLoc)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
CPU_Message("%s: pc: %X target: %X Loc: %X JumpLoc: %X immediate: %X", __FUNCTION__, pc, target, (uint32_t)Loc, (uint32_t)JumpLoc, immediate);
CPU_Message("%s: writing %d to %X", __FUNCTION__, immediate, Loc);
CodeLog("%s: pc: %X target: %X Loc: %X JumpLoc: %X immediate: %X", __FUNCTION__, pc, target, (uint32_t)Loc, (uint32_t)JumpLoc, immediate);
CodeLog("%s: writing %d to %X", __FUNCTION__, immediate, Loc);
if (op->BranchImm.opcode == 0x1C)
{
op->BranchImm.imm = immediate;
@ -1526,7 +1531,7 @@ void CArmOps::SetJump20(uint32_t * Loc, uint32_t * JumpLoc)
int32_t immediate_check = immediate & ~0xFFFFF;
if (immediate_check != 0 && immediate_check != ~0xFFFFF)
{
CPU_Message("%s: target %X pc %X immediate: %X", __FUNCTION__, target, pc, immediate);
CodeLog("%s: target %X pc %X immediate: %X", __FUNCTION__, target, pc, immediate);
g_Notify->BreakPoint(__FILE__, __LINE__);
}
Arm32Opcode op = { 0 };
@ -1558,7 +1563,7 @@ void CArmOps::SetJump20(uint32_t * Loc, uint32_t * JumpLoc)
uint32_t OriginalValue = *Loc;
*Loc = op.Hex;
CPU_Message("%s: OriginalValue %X New Value %X JumpLoc: %X Loc: %X immediate: %X immediate_check = %X", __FUNCTION__, OriginalValue, *Loc, JumpLoc, Loc, immediate, immediate_check);
CodeLog("%s: OriginalValue %X New Value %X JumpLoc: %X Loc: %X immediate: %X immediate_check = %X", __FUNCTION__, OriginalValue, *Loc, JumpLoc, Loc, immediate, immediate_check);
}
void * CArmOps::GetAddressOf(int value, ...)

View File

@ -1,7 +1,13 @@
#pragma once
#if defined(__arm__) || defined(_M_ARM)
#if !defined(_MSC_VER) && !defined(_Printf_format_string_)
#define _Printf_format_string_
#endif
#include <Project64-core/Settings/DebugSettings.h>
class CCodeBlock;
class CArmRegInfo;
class CArmOps :
@ -143,102 +149,106 @@ public:
ItMask_EEE,
};
protected:
CArmOps(CCodeBlock & CodeBlock, CArmRegInfo & RegWorkingSet);
// Logging functions
static void WriteArmComment(const char * Comment);
static void WriteArmLabel(const char * Label);
void WriteArmComment(const char * Comment);
void WriteArmLabel(const char * Label);
static void AddArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
static void AddConstToArmReg(ArmReg DestReg, uint32_t Const);
static void AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const);
static void AndConstToVariable(void *Variable, const char * VariableName, uint32_t Const);
static void AndConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const);
static void AndArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
static void ArmBreakPoint(const char * FileName, uint32_t LineNumber);
static void ArmNop(void);
static void BranchLabel8(ArmCompareType CompareType, const char * Label);
static void BranchLabel20(ArmCompareType CompareType, const char * Label);
static void CallFunction(void * Function, const char * FunctionName);
static void CompareArmRegToConst(ArmReg Reg, uint32_t value);
static void CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2);
static void IfBlock(ArmItMask mask, ArmCompareType CompareType);
static void LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, uint16_t offset);
static void LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, ArmReg RegPointer2, uint8_t shift);
static void LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, uint8_t Offset, const char * comment = nullptr);
static void LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, ArmReg RegPointer2, uint8_t shift);
static void LoadArmRegPointerToFloatReg(ArmReg RegPointer, ArmFpuSingle Reg, uint8_t Offset);
static void LoadFloatingPointControlReg(ArmReg DestReg);
static void MoveArmRegArmReg(ArmReg DestReg, ArmReg SourceReg);
static void MoveArmRegToVariable(ArmReg Reg, void * Variable, const char * VariableName);
static void MoveConstToArmReg(ArmReg DestReg, uint16_t Const, const char * comment = nullptr);
static void MoveConstToArmRegTop(ArmReg DestReg, uint16_t Const, const char * comment = nullptr);
static void MoveConstToArmReg(ArmReg DestReg, uint32_t Const, const char * comment = nullptr);
static void MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName);
static void MoveFloatRegToVariable(ArmFpuSingle reg, void * Variable, const char * VariableName);
static void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg);
static void MoveVariableToFloatReg(void * Variable, const char * VariableName, ArmFpuSingle reg);
static void OrArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2, uint32_t shift);
static void OrConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t value);
static void OrConstToVariable(void * Variable, const char * VariableName, uint32_t value);
static void MulF32(ArmFpuSingle DestReg, ArmFpuSingle SourceReg1, ArmFpuSingle SourceReg2);
static void PushArmReg(uint16_t Registers);
static void PopArmReg(uint16_t Registers);
static void ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
static void ShiftRightUnsignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
static void ShiftLeftImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
static void SignExtendByte(ArmReg Reg);
static void StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, uint8_t Offset, const char * comment = nullptr);
static void StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, ArmReg RegPointer2, uint8_t shift);
static void StoreFloatingPointControlReg(ArmReg SourceReg);
static void StoreFloatRegToArmRegPointer(ArmFpuSingle Reg, ArmReg RegPointer, uint8_t Offset);
static void SubArmRegFromArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
static void SubConstFromArmReg(ArmReg Reg, ArmReg SourceReg, uint32_t Const);
static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName);
static void TestVariable(uint32_t Const, void * Variable, const char * VariableName);
static void XorConstToArmReg(ArmReg DestReg, uint32_t value);
static void XorArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg);
static void XorArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
void AddArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
void AddConstToArmReg(ArmReg DestReg, uint32_t Const);
void AddConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const);
void AndConstToVariable(void *Variable, const char * VariableName, uint32_t Const);
void AndConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t Const);
void AndArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
void ArmBreakPoint(const char * FileName, uint32_t LineNumber);
void ArmNop(void);
void BranchLabel8(ArmCompareType CompareType, const char * Label);
void BranchLabel20(ArmCompareType CompareType, const char * Label);
void CallFunction(void * Function, const char * FunctionName);
void CompareArmRegToConst(ArmReg Reg, uint32_t value);
void CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2);
void IfBlock(ArmItMask mask, ArmCompareType CompareType);
void LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, uint16_t offset);
void LoadArmRegPointerByteToArmReg(ArmReg DestReg, ArmReg RegPointer, ArmReg RegPointer2, uint8_t shift);
void LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, uint8_t Offset, const char * comment = nullptr);
void LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, ArmReg RegPointer2, uint8_t shift);
void LoadArmRegPointerToFloatReg(ArmReg RegPointer, ArmFpuSingle Reg, uint8_t Offset);
void LoadFloatingPointControlReg(ArmReg DestReg);
void MoveArmRegArmReg(ArmReg DestReg, ArmReg SourceReg);
void MoveArmRegToVariable(ArmReg Reg, void * Variable, const char * VariableName);
void MoveConstToArmReg(ArmReg DestReg, uint16_t Const, const char * comment = nullptr);
void MoveConstToArmRegTop(ArmReg DestReg, uint16_t Const, const char * comment = nullptr);
void MoveConstToArmReg(ArmReg DestReg, uint32_t Const, const char * comment = nullptr);
void MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName);
void MoveFloatRegToVariable(ArmFpuSingle reg, void * Variable, const char * VariableName);
void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg);
void MoveVariableToFloatReg(void * Variable, const char * VariableName, ArmFpuSingle reg);
void OrArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2, uint32_t shift);
void OrConstToArmReg(ArmReg DestReg, ArmReg SourceReg, uint32_t value);
void OrConstToVariable(void * Variable, const char * VariableName, uint32_t value);
void MulF32(ArmFpuSingle DestReg, ArmFpuSingle SourceReg1, ArmFpuSingle SourceReg2);
void PushArmReg(uint16_t Registers);
void PopArmReg(uint16_t Registers);
void ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
void ShiftRightUnsignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
void ShiftLeftImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift);
void SignExtendByte(ArmReg Reg);
void StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, uint8_t Offset, const char * comment = nullptr);
void StoreArmRegToArmRegPointer(ArmReg DestReg, ArmReg RegPointer, ArmReg RegPointer2, uint8_t shift);
void StoreFloatingPointControlReg(ArmReg SourceReg);
void StoreFloatRegToArmRegPointer(ArmFpuSingle Reg, ArmReg RegPointer, uint8_t Offset);
void SubArmRegFromArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
void SubConstFromArmReg(ArmReg Reg, ArmReg SourceReg, uint32_t Const);
void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName);
void TestVariable(uint32_t Const, void * Variable, const char * VariableName);
void XorConstToArmReg(ArmReg DestReg, uint32_t value);
void XorArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg);
void XorArmRegToArmReg(ArmReg DestReg, ArmReg SourceReg1, ArmReg SourceReg2);
static void * GetAddressOf(int32_t value, ...);
static void SetJump8(uint8_t * Loc, uint8_t * JumpLoc);
static void SetJump20(uint32_t * Loc, uint32_t * JumpLoc);
static void FlushPopArmReg(void);
void * GetAddressOf(int32_t value, ...);
void SetJump8(uint8_t * Loc, uint8_t * JumpLoc);
void SetJump20(uint32_t * Loc, uint32_t * JumpLoc);
void FlushPopArmReg(void);
static CArmRegInfo m_RegWorkingSet;
protected:
static const char * ArmRegName(ArmReg Reg);
static uint32_t PushPopRegisterSize(uint16_t Registers);
static std::string PushPopRegisterList(uint16_t Registers);
const char * ArmRegName(ArmReg Reg);
uint32_t PushPopRegisterSize(uint16_t Registers);
std::string PushPopRegisterList(uint16_t Registers);
private:
friend class CArmRegInfo;
CArmOps(void);
CArmOps(const CArmOps&);
CArmOps& operator=(const CArmOps&);
static void PreOpCheck(ArmReg DestReg, bool AllowedInItBlock, const char * FileName, uint32_t LineNumber);
static void BreakPointNotification(const char * FileName, uint32_t LineNumber);
static bool ArmCompareInverse(ArmCompareType CompareType);
static ArmCompareType ArmCompareInverseType(ArmCompareType CompareType);
static const char * ArmCompareSuffix(ArmCompareType CompareType);
static const char * ArmFpuSingleName(ArmFpuSingle Reg);
static const char * ArmItMaskName(ArmItMask mask);
static const char * ArmCurrentItCondition();
void CodeLog(_Printf_format_string_ const char * Text, ...);
static void ProgressItBlock(void);
void PreOpCheck(ArmReg DestReg, bool AllowedInItBlock, const char * FileName, uint32_t LineNumber);
void BreakPointNotification(const char * FileName, uint32_t LineNumber);
bool ArmCompareInverse(ArmCompareType CompareType);
ArmCompareType ArmCompareInverseType(ArmCompareType CompareType);
const char * ArmCompareSuffix(ArmCompareType CompareType);
const char * ArmFpuSingleName(ArmFpuSingle Reg);
const char * ArmItMaskName(ArmItMask mask);
const char * ArmCurrentItCondition();
static bool CanThumbCompressConst(uint32_t value);
static uint16_t ThumbCompressConst(uint32_t value);
void ProgressItBlock(void);
static void AddCode8(uint8_t value);
static void AddCode16(uint16_t value);
static void AddCode32(uint32_t value);
bool CanThumbCompressConst(uint32_t value);
uint16_t ThumbCompressConst(uint32_t value);
static bool m_InItBlock;
static int m_ItBlockInstruction;
static ArmCompareType m_ItBlockCompareType;
static ArmItMask m_ItBlockMask;
static ArmReg m_LastStoreReg;
static uint16_t m_PopRegisters;
static uint16_t m_PushRegisters;
void AddCode8(uint8_t value);
void AddCode16(uint16_t value);
void AddCode32(uint32_t value);
CCodeBlock & m_CodeBlock;
CArmRegInfo & m_RegWorkingSet;
bool m_InItBlock;
int m_ItBlockInstruction;
ArmCompareType m_ItBlockCompareType;
ArmItMask m_ItBlockMask;
ArmReg m_LastStoreReg;
uint16_t m_PopRegisters;
uint16_t m_PushRegisters;
};
#define AddressOf(Addr) CArmOps::GetAddressOf(5,(Addr))

View File

@ -1,27 +1,38 @@
#pragma once
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/Mips/Register.h>
#include <Project64-core/N64System/Mips/R4300iOpcode.h>
#include <Project64-core/N64System/Recompiler/ExitInfo.h>
#include <Project64-core/N64System/Recompiler/RegInfo.h>
#include <Project64-core/N64System/Recompiler/RecompilerOps.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmOps.h>
#include <Project64-core\Settings\GameSettings.h>
#include <Project64-core/N64System/Recompiler/JumpInfo.h>
#include <Project64-core/N64System/Interpreter/InterpreterOps.h>
#include <Project64-core/Settings/N64SystemSettings.h>
#include <Project64-core/Settings/RecompilerSettings.h>
#include <Project64-core/Settings/GameSettings.h>
class CCodeBlock;
class CCodeSection;
class CArmRecompilerOps :
public CRecompilerOps,
private CArmOps,
protected CSystemRegisters,
protected R4300iOp,
protected CN64SystemSettings,
protected CRecompilerSettings,
private CGameSettings
{
public:
CArmRecompilerOps(CMipsMemoryVM & MMU);
CArmRecompilerOps(CMipsMemoryVM & MMU, CCodeBlock & CodeBlock);
~CArmRecompilerOps();
// Trap functions
void Compile_TrapCompare(TRAP_COMPARE CompareType);
void Compile_TrapCompare(RecompilerTrapCompare CompareType);
// Branch functions
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, bool Link);
void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link);
void Compile_BranchCompare(RecompilerBranchCompare CompareType);
void Compile_Branch(RecompilerBranchCompare CompareType, bool Link);
void Compile_BranchLikely(RecompilerBranchCompare CompareType, bool Link);
void BNE_Compare();
void BEQ_Compare();
void BGTZ_Compare();
@ -191,7 +202,6 @@ public:
// Other functions
void UnknownOpcode();
private:
void EnterCodeBlock();
void ExitCodeBlock();
void CompileExitCode();
@ -199,83 +209,90 @@ private:
void CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter);
void OutputRegisterState(const CRegInfo & SyncTo, const CRegInfo & CurrentSet) const;
void SyncRegState(const CRegInfo & SyncTo);
bool SetupRegisterForLoop(CCodeBlock * BlockInfo, const CRegInfo & RegSet);
bool SetupRegisterForLoop(CCodeBlock & BlockInfo, const CRegInfo & RegSet);
CRegInfo & GetRegWorkingSet(void);
void SetRegWorkingSet(const CRegInfo & RegInfo);
bool InheritParentInfo();
void LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID = -1, uint32_t FromSectionID = -1);
void JumpToSection( CCodeSection * Section);
void JumpToSection(CCodeSection * Section);
void JumpToUnknown(CJumpInfo * JumpInfo);
void SetCurrentPC(uint32_t ProgramCounter);
uint32_t GetCurrentPC(void);
void SetCurrentSection(CCodeSection * section);
void SetNextStepType(PIPELINE_STAGE StepType);
PIPELINE_STAGE GetNextStepType( void );
const R4300iOpcode & GetOpcode ( void ) const;
PIPELINE_STAGE GetNextStepType(void);
const R4300iOpcode & GetOpcode(void) const;
void PreCompileOpcode(void);
void PostCompileOpcode ( void );
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, ExitReason reason);
void PostCompileOpcode(void);
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, ExitReason Reason);
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, ExitReason reason, CArmOps::ArmCompareType CompareType);
static void UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles);
void CompileReadTLBMiss(CArmOps::ArmReg AddressReg, CArmOps::ArmReg LookUpReg);
void CompileWriteTLBMiss(CArmOps::ArmReg AddressReg, CArmOps::ArmReg LookUpReg);
void UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles);
void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false, bool UpdateTimer = true);
void CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet);
void CompileReadTLBMiss(ArmReg AddressReg, ArmReg LookUpReg);
void CompileWriteTLBMiss(ArmReg AddressReg, ArmReg LookUpReg);
void CompileExecuteBP(void);
void CompileExecuteDelaySlotBP(void);
CArmOps & Assembler() { return m_Assembler; }
// Helper functions
typedef CRegInfo::REG_STATE REG_STATE;
static inline REG_STATE GetMipsRegState(int32_t Reg) { return m_RegWorkingSet.GetMipsRegState(Reg); }
static inline uint64_t GetMipsReg(int32_t Reg) { return m_RegWorkingSet.GetMipsReg(Reg); }
static inline uint32_t GetMipsRegLo(int32_t Reg) { return m_RegWorkingSet.GetMipsRegLo(Reg); }
static inline int32_t GetMipsRegLo_S(int32_t Reg) { return m_RegWorkingSet.GetMipsRegLo_S(Reg); }
static inline uint32_t GetMipsRegHi(int32_t Reg) { return m_RegWorkingSet.GetMipsRegHi(Reg); }
static inline int32_t GetMipsRegHi_S(int32_t Reg) { return m_RegWorkingSet.GetMipsRegHi_S(Reg); }
static inline ArmReg GetMipsRegMapLo(int32_t Reg) { return m_RegWorkingSet.GetMipsRegMapLo(Reg); }
static inline ArmReg GetMipsRegMapHi(int32_t Reg) { return m_RegWorkingSet.GetMipsRegMapHi(Reg); }
REG_STATE GetMipsRegState(int32_t Reg) { return m_RegWorkingSet.GetMipsRegState(Reg); }
uint64_t GetMipsReg(int32_t Reg) { return m_RegWorkingSet.GetMipsReg(Reg); }
uint32_t GetMipsRegLo(int32_t Reg) { return m_RegWorkingSet.GetMipsRegLo(Reg); }
int32_t GetMipsRegLo_S(int32_t Reg) { return m_RegWorkingSet.GetMipsRegLo_S(Reg); }
uint32_t GetMipsRegHi(int32_t Reg) { return m_RegWorkingSet.GetMipsRegHi(Reg); }
int32_t GetMipsRegHi_S(int32_t Reg) { return m_RegWorkingSet.GetMipsRegHi_S(Reg); }
CArmOps::ArmReg GetMipsRegMapLo(int32_t Reg) { return m_RegWorkingSet.GetMipsRegMapLo(Reg); }
CArmOps::ArmReg GetMipsRegMapHi(int32_t Reg) { return m_RegWorkingSet.GetMipsRegMapHi(Reg); }
static inline bool IsKnown(int32_t Reg) { return m_RegWorkingSet.IsKnown(Reg); }
static inline bool IsUnknown(int32_t Reg) { return m_RegWorkingSet.IsUnknown(Reg); }
static inline bool IsMapped(int32_t Reg) { return m_RegWorkingSet.IsMapped(Reg); }
static inline bool IsConst(int32_t Reg) { return m_RegWorkingSet.IsConst(Reg); }
static inline bool IsSigned(int32_t Reg) { return m_RegWorkingSet.IsSigned(Reg); }
static inline bool IsUnsigned(int32_t Reg) { return m_RegWorkingSet.IsUnsigned(Reg); }
static inline bool Is32Bit(int32_t Reg) { return m_RegWorkingSet.Is32Bit(Reg); }
static inline bool Is64Bit(int32_t Reg) { return m_RegWorkingSet.Is64Bit(Reg); }
static inline bool Is32BitMapped(int32_t Reg) { return m_RegWorkingSet.Is32BitMapped(Reg); }
static inline bool Is64BitMapped(int32_t Reg) { return m_RegWorkingSet.Is64BitMapped(Reg); }
static inline void Map_GPR_32bit(int32_t Reg, bool SignValue, int32_t MipsRegToLoad) { m_RegWorkingSet.Map_GPR_32bit(Reg, SignValue, MipsRegToLoad); }
static inline void Map_GPR_64bit(int32_t Reg, int32_t MipsRegToLoad) { m_RegWorkingSet.Map_GPR_64bit(Reg, MipsRegToLoad); }
static inline void UnMap_GPR(uint32_t Reg, bool WriteBackValue){ m_RegWorkingSet.UnMap_GPR(Reg, WriteBackValue); }
static inline void WriteBack_GPR(uint32_t Reg, bool Unmapping){ m_RegWorkingSet.WriteBack_GPR(Reg, Unmapping); }
static inline ArmReg Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord) { return m_RegWorkingSet.Map_TempReg(Reg, MipsReg, LoadHiWord); }
static inline ArmReg Map_Variable(CArmRegInfo::VARIABLE_MAPPED variable, ArmReg Reg = Arm_Any) { return m_RegWorkingSet.Map_Variable(variable, Reg); }
bool IsKnown(int32_t Reg) { return m_RegWorkingSet.IsKnown(Reg); }
bool IsUnknown(int32_t Reg) { return m_RegWorkingSet.IsUnknown(Reg); }
bool IsMapped(int32_t Reg) { return m_RegWorkingSet.IsMapped(Reg); }
bool IsConst(int32_t Reg) { return m_RegWorkingSet.IsConst(Reg); }
bool IsSigned(int32_t Reg) { return m_RegWorkingSet.IsSigned(Reg); }
bool IsUnsigned(int32_t Reg) { return m_RegWorkingSet.IsUnsigned(Reg); }
bool Is32Bit(int32_t Reg) { return m_RegWorkingSet.Is32Bit(Reg); }
bool Is64Bit(int32_t Reg) { return m_RegWorkingSet.Is64Bit(Reg); }
bool Is32BitMapped(int32_t Reg) { return m_RegWorkingSet.Is32BitMapped(Reg); }
bool Is64BitMapped(int32_t Reg) { return m_RegWorkingSet.Is64BitMapped(Reg); }
void Map_GPR_32bit(int32_t Reg, bool SignValue, int32_t MipsRegToLoad) { m_RegWorkingSet.Map_GPR_32bit(Reg, SignValue, MipsRegToLoad); }
void Map_GPR_64bit(int32_t Reg, int32_t MipsRegToLoad) { m_RegWorkingSet.Map_GPR_64bit(Reg, MipsRegToLoad); }
void UnMap_GPR(uint32_t Reg, bool WriteBackValue){ m_RegWorkingSet.UnMap_GPR(Reg, WriteBackValue); }
void WriteBack_GPR(uint32_t Reg, bool Unmapping){ m_RegWorkingSet.WriteBack_GPR(Reg, Unmapping); }
CArmOps::ArmReg Map_TempReg(CArmOps::ArmReg Reg, int32_t MipsReg, bool LoadHiWord) { return m_RegWorkingSet.Map_TempReg(Reg, MipsReg, LoadHiWord); }
CArmOps::ArmReg Map_Variable(CArmRegInfo::VARIABLE_MAPPED variable, CArmOps::ArmReg Reg = CArmOps::Arm_Any) { return m_RegWorkingSet.Map_Variable(variable, Reg); }
static inline void ResetRegProtection() { m_RegWorkingSet.ResetRegProtection(); }
static inline void FixRoundModel(CRegInfo::FPU_ROUND RoundMethod) { m_RegWorkingSet.FixRoundModel(RoundMethod); }
void ResetRegProtection() { m_RegWorkingSet.ResetRegProtection(); }
void FixRoundModel(CRegInfo::FPU_ROUND RoundMethod) { m_RegWorkingSet.FixRoundModel(RoundMethod); }
static inline void ProtectGPR(uint32_t Reg) { m_RegWorkingSet.ProtectGPR(Reg); }
static inline void UnProtectGPR(uint32_t Reg) { m_RegWorkingSet.UnProtectGPR(Reg); }
static inline bool UnMap_ArmReg(ArmReg Reg) { return m_RegWorkingSet.UnMap_ArmReg(Reg); }
void ProtectGPR(uint32_t Reg) { m_RegWorkingSet.ProtectGPR(Reg); }
void UnProtectGPR(uint32_t Reg) { m_RegWorkingSet.UnProtectGPR(Reg); }
bool UnMap_ArmReg(CArmOps::ArmReg Reg) { return m_RegWorkingSet.UnMap_ArmReg(Reg); }
void SW(bool bCheckLLbit);
void SW_Const(uint32_t Value, uint32_t VAddr);
void SW_Register(ArmReg Reg, uint32_t VAddr);
void SW_Register(CArmOps::ArmReg Reg, uint32_t VAddr);
void LW(bool ResultSigned, bool bRecordLLBit);
void LB_KnownAddress(ArmReg Reg, uint32_t VAddr, bool SignExtend);
void LW_KnownAddress(ArmReg Reg, uint32_t VAddr);
void LB_KnownAddress(CArmOps::ArmReg Reg, uint32_t VAddr, bool SignExtend);
void LW_KnownAddress(CArmOps::ArmReg Reg, uint32_t VAddr);
void CompileInterpterCall (void * Function, const char * FunctionName);
void OverflowDelaySlot(bool TestTimer);
EXIT_LIST m_ExitInfo;
CMipsMemoryVM & m_MMU;
CCodeBlock & m_CodeBlock;
CArmOps m_Assembler;
PIPELINE_STAGE m_PipelineStage;
uint32_t m_CompilePC;
R4300iOpcode m_Opcode;
CArmRegInfo m_RegWorkingSet;
CCodeSection * m_Section;
CRegInfo m_RegBeforeDelay;
bool m_EffectDelaySlot;
static uint32_t m_TempValue;
};

View File

@ -3,16 +3,18 @@
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/N64System.h>
#include <Project64-core/N64System/Recompiler/RecompilerCodeLog.h>
#include <Project64-core/N64System/Recompiler/Recompiler.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h>
CArmRegInfo::CArmRegInfo() :
CArmRegInfo::CArmRegInfo(CCodeBlock & CodeBlock, CArmOps & Assembler) :
m_CodeBlock(CodeBlock),
m_Assembler(Assembler),
m_InCallDirect(false)
{
for (int32_t i = 0; i < 32; i++)
{
m_RegMapLo[i] = Arm_Unknown;
m_RegMapHi[i] = Arm_Unknown;
m_RegMapLo[i] = CArmOps::Arm_Unknown;
m_RegMapHi[i] = CArmOps::Arm_Unknown;
}
for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++)
@ -24,7 +26,9 @@ CArmRegInfo::CArmRegInfo() :
}
}
CArmRegInfo::CArmRegInfo(const CArmRegInfo& rhs)
CArmRegInfo::CArmRegInfo(const CArmRegInfo& rhs) :
m_CodeBlock(rhs.m_CodeBlock),
m_Assembler(rhs.m_CodeBlock.RecompilerOps()->Assembler())
{
*this = rhs;
}
@ -76,7 +80,7 @@ bool CArmRegInfo::operator==(const CArmRegInfo& right) const
return true;
}
bool CArmRegInfo::ShouldPushPopReg(ArmReg Reg)
bool CArmRegInfo::ShouldPushPopReg(CArmOps::ArmReg Reg)
{
if (m_ArmReg_MappedTo[Reg] == NotMapped)
{
@ -93,21 +97,21 @@ void CArmRegInfo::BeforeCallDirect(void)
{
static uint32_t PushPopRegisterList[] =
{
ArmPushPop_R0, ArmPushPop_R1, ArmPushPop_R2, ArmPushPop_R3, ArmPushPop_R4,
ArmPushPop_R5, ArmPushPop_R6, ArmPushPop_R7, ArmPushPop_R8, ArmPushPop_R9,
ArmPushPop_R10, ArmPushPop_R11, ArmPushPop_R12
CArmOps::ArmPushPop_R0, CArmOps::ArmPushPop_R1, CArmOps::ArmPushPop_R2, CArmOps::ArmPushPop_R3, CArmOps::ArmPushPop_R4,
CArmOps::ArmPushPop_R5, CArmOps::ArmPushPop_R6, CArmOps::ArmPushPop_R7, CArmOps::ArmPushPop_R8, CArmOps::ArmPushPop_R9,
CArmOps::ArmPushPop_R10, CArmOps::ArmPushPop_R11, CArmOps::ArmPushPop_R12
};
static ArmReg RegisterList[] =
static CArmOps::ArmReg RegisterList[] =
{
Arm_R0, Arm_R1, Arm_R2, Arm_R3, Arm_R4,
Arm_R5, Arm_R6, Arm_R7, Arm_R8, Arm_R9,
Arm_R10, Arm_R11, Arm_R12
CArmOps::Arm_R0, CArmOps::Arm_R1, CArmOps::Arm_R2, CArmOps::Arm_R3, CArmOps::Arm_R4,
CArmOps::Arm_R5, CArmOps::Arm_R6, CArmOps::Arm_R7, CArmOps::Arm_R8, CArmOps::Arm_R9,
CArmOps::Arm_R10, CArmOps::Arm_R11, CArmOps::Arm_R12
};
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -124,7 +128,7 @@ void CArmRegInfo::BeforeCallDirect(void)
return;
}
if ((PushPopRegisterSize(PushPopRegisters) % 8) != 0)
if ((m_Assembler.PushPopRegisterSize(PushPopRegisters) % 8) != 0)
{
bool Added = false;
for (int i = 0; i < (sizeof(RegisterList) / sizeof(RegisterList[0])); i++)
@ -139,42 +143,42 @@ void CArmRegInfo::BeforeCallDirect(void)
}
if (!Added)
{
ArmReg reg = FreeArmReg(false);
CPU_Message(" Freed %s", ArmRegName(reg));
CArmOps::ArmReg reg = FreeArmReg(false);
m_CodeBlock.Log(" Freed %s", m_Assembler.ArmRegName(reg));
PushPopRegisters = 0;
for (int i = 0; i < (sizeof(RegisterList) / sizeof(RegisterList[0])); i++)
{
if (ShouldPushPopReg(RegisterList[i])) { PushPopRegisters |= PushPopRegisterList[i]; }
}
}
if ((PushPopRegisterSize(PushPopRegisters) % 8) != 0)
if ((m_Assembler.PushPopRegisterSize(PushPopRegisters) % 8) != 0)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
m_InCallDirect = true;
PushArmReg(PushPopRegisters);
m_Assembler.PushArmReg(PushPopRegisters);
}
void CArmRegInfo::AfterCallDirect(void)
{
static uint32_t PushPopRegisterList[] =
{
ArmPushPop_R0, ArmPushPop_R1, ArmPushPop_R2, ArmPushPop_R3, ArmPushPop_R4,
ArmPushPop_R5, ArmPushPop_R6, ArmPushPop_R7, ArmPushPop_R8, ArmPushPop_R9,
ArmPushPop_R10, ArmPushPop_R11, ArmPushPop_R12, ArmPushPop_LR, ArmPushPop_PC
CArmOps::ArmPushPop_R0, CArmOps::ArmPushPop_R1, CArmOps::ArmPushPop_R2, CArmOps::ArmPushPop_R3, CArmOps::ArmPushPop_R4,
CArmOps::ArmPushPop_R5, CArmOps::ArmPushPop_R6, CArmOps::ArmPushPop_R7, CArmOps::ArmPushPop_R8, CArmOps::ArmPushPop_R9,
CArmOps::ArmPushPop_R10, CArmOps::ArmPushPop_R11, CArmOps::ArmPushPop_R12, CArmOps::ArmPushPop_LR, CArmOps::ArmPushPop_PC
};
static ArmReg RegisterList[] =
static CArmOps::ArmReg RegisterList[] =
{
Arm_R0, Arm_R1, Arm_R2, Arm_R3, Arm_R4,
Arm_R5, Arm_R6, Arm_R7, Arm_R8, Arm_R9,
Arm_R10, Arm_R11, Arm_R12, ArmRegLR, ArmRegPC,
CArmOps::Arm_R0, CArmOps::Arm_R1, CArmOps::Arm_R2, CArmOps::Arm_R3, CArmOps::Arm_R4,
CArmOps::Arm_R5, CArmOps::Arm_R6, CArmOps::Arm_R7, CArmOps::Arm_R8, CArmOps::Arm_R9,
CArmOps::Arm_R10, CArmOps::Arm_R11, CArmOps::Arm_R12, CArmOps::ArmRegLR, CArmOps::ArmRegPC,
};
if (!m_InCallDirect)
{
CPU_Message("%s: Not in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: Not in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -187,7 +191,7 @@ void CArmRegInfo::AfterCallDirect(void)
if (PushPopRegisters != 0)
{
if ((PushPopRegisterSize(PushPopRegisters) % 8) != 0)
if ((m_Assembler.PushPopRegisterSize(PushPopRegisters) % 8) != 0)
{
for (int i = 0; i < (sizeof(RegisterList) / sizeof(RegisterList[0])); i++)
{
@ -199,7 +203,7 @@ void CArmRegInfo::AfterCallDirect(void)
break;
}
}
PopArmReg(PushPopRegisters);
m_Assembler.PopArmReg(PushPopRegisters);
}
SetRoundingModel(CRegInfo::RoundUnknown);
@ -210,7 +214,7 @@ void CArmRegInfo::FixRoundModel(FPU_ROUND RoundMethod)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -219,13 +223,13 @@ void CArmRegInfo::FixRoundModel(FPU_ROUND RoundMethod)
{
return;
}
CPU_Message(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s", RoundingModelName(GetRoundingModel()), RoundingModelName(RoundMethod));
m_CodeBlock.Log(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s", RoundingModelName(GetRoundingModel()), RoundingModelName(RoundMethod));
if (RoundMethod == RoundDefault)
{
m_RegWorkingSet.BeforeCallDirect();
MoveVariableToArmReg(_RoundingModel, "_RoundingModel", Arm_R0);
CallFunction((void *)fesetround, "fesetround");
m_RegWorkingSet.AfterCallDirect();
BeforeCallDirect();
m_Assembler.MoveVariableToArmReg(_RoundingModel, "_RoundingModel", CArmOps::Arm_R0);
m_Assembler.CallFunction((void *)fesetround, "fesetround");
AfterCallDirect();
}
else
{
@ -237,12 +241,12 @@ void CArmRegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
ArmReg Reg;
CArmOps::ArmReg Reg;
if (MipsReg == 0)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
@ -259,13 +263,13 @@ void CArmRegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
return;
}
SetArmRegProtected(Reg, true);
CPU_Message(" regcache: allocate %s to %s", ArmRegName(Reg), CRegName::GPR[MipsReg]);
m_CodeBlock.Log(" regcache: allocate %s to %s", m_Assembler.ArmRegName(Reg), CRegName::GPR[MipsReg]);
}
else
{
if (Is64Bit(MipsReg))
{
CPU_Message(" regcache: unallocate %s from high 32-bit of %s", ArmRegName(GetMipsRegMapHi(MipsReg)), CRegName::GPR_Hi[MipsReg]);
m_CodeBlock.Log(" regcache: unallocate %s from high 32-bit of %s", m_Assembler.ArmRegName(GetMipsRegMapHi(MipsReg)), CRegName::GPR_Hi[MipsReg]);
SetArmRegMapOrder(GetMipsRegMapHi(MipsReg), 0);
SetArmRegMapped(GetMipsRegMapHi(MipsReg), NotMapped);
SetArmRegProtected(GetMipsRegMapHi(MipsReg), false);
@ -273,12 +277,12 @@ void CArmRegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
}
Reg = GetMipsRegMapLo(MipsReg);
}
for (int32_t count = 0; count <= Arm_R15; count++)
for (int32_t count = 0; count <= CArmOps::Arm_R15; count++)
{
uint32_t Count = GetArmRegMapOrder((ArmReg)count);
uint32_t Count = GetArmRegMapOrder((CArmOps::ArmReg)count);
if (Count > 0)
{
SetArmRegMapOrder((ArmReg)count, Count + 1);
SetArmRegMapOrder((CArmOps::ArmReg)count, Count + 1);
}
}
SetArmRegMapOrder(Reg, 1);
@ -287,25 +291,25 @@ void CArmRegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
{
if (IsUnknown(MipsRegToLoad))
{
ArmReg GprReg = Map_Variable(VARIABLE_GPR);
LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsRegToLoad << 3), CRegName::GPR_Lo[MipsRegToLoad]);
CArmOps::ArmReg GprReg = Map_Variable(VARIABLE_GPR);
m_Assembler.LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsRegToLoad << 3), CRegName::GPR_Lo[MipsRegToLoad]);
SetArmRegProtected(GprReg, false);
}
else if (IsMapped(MipsRegToLoad))
{
if (MipsReg != MipsRegToLoad)
{
AddConstToArmReg(Reg, GetMipsRegMapLo(MipsRegToLoad), 0);
m_Assembler.AddConstToArmReg(Reg, GetMipsRegMapLo(MipsRegToLoad), 0);
}
}
else
{
MoveConstToArmReg(Reg, GetMipsRegLo(MipsRegToLoad));
m_Assembler.MoveConstToArmReg(Reg, GetMipsRegLo(MipsRegToLoad));
}
}
else if (MipsRegToLoad == 0)
{
MoveConstToArmReg(Reg, (uint32_t)0);
m_Assembler.MoveConstToArmReg(Reg, (uint32_t)0);
}
SetArmRegMapped(Reg, GPR_Mapped);
SetArmRegProtected(Reg, true);
@ -317,12 +321,12 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
ArmReg regHi, reglo;
CArmOps::ArmReg regHi, reglo;
int32_t count;
if (MipsReg == 0)
@ -353,8 +357,8 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
}
SetArmRegProtected(reglo, true);
CPU_Message(" regcache: allocate %s to hi word of %s", ArmRegName(regHi), CRegName::GPR[MipsReg]);
CPU_Message(" regcache: allocate %s to low word of %s", ArmRegName(reglo), CRegName::GPR[MipsReg]);
m_CodeBlock.Log(" regcache: allocate %s to hi word of %s", m_Assembler.ArmRegName(regHi), CRegName::GPR[MipsReg]);
m_CodeBlock.Log(" regcache: allocate %s to low word of %s", m_Assembler.ArmRegName(reglo), CRegName::GPR[MipsReg]);
}
else
{
@ -371,7 +375,7 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
}
SetArmRegProtected(regHi, true);
CPU_Message(" regcache: allocate %s to hi word of %s", ArmRegName(regHi), CRegName::GPR[MipsReg]);
m_CodeBlock.Log(" regcache: allocate %s to hi word of %s", m_Assembler.ArmRegName(regHi), CRegName::GPR[MipsReg]);
}
else
{
@ -379,12 +383,12 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
}
}
for (int32_t count = 0; count <= Arm_R15; count++)
for (int32_t count = 0; count <= CArmOps::Arm_R15; count++)
{
uint32_t Count = GetArmRegMapOrder((ArmReg)count);
uint32_t Count = GetArmRegMapOrder((CArmOps::ArmReg)count);
if (Count > 0)
{
SetArmRegMapOrder((ArmReg)count, Count + 1);
SetArmRegMapOrder((CArmOps::ArmReg)count, Count + 1);
}
}
SetArmRegMapOrder(regHi, 1);
@ -394,9 +398,9 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
{
if (IsUnknown(MipsRegToLoad))
{
ArmReg GprReg = Map_Variable(VARIABLE_GPR);
LoadArmRegPointerToArmReg(regHi, GprReg, (uint8_t)(MipsRegToLoad << 3) + 4, CRegName::GPR_Hi[MipsRegToLoad]);
LoadArmRegPointerToArmReg(reglo, GprReg, (uint8_t)(MipsRegToLoad << 3), CRegName::GPR_Lo[MipsRegToLoad]);
CArmOps::ArmReg GprReg = Map_Variable(VARIABLE_GPR);
m_Assembler.LoadArmRegPointerToArmReg(regHi, GprReg, (uint8_t)(MipsRegToLoad << 3) + 4, CRegName::GPR_Hi[MipsRegToLoad]);
m_Assembler.LoadArmRegPointerToArmReg(reglo, GprReg, (uint8_t)(MipsRegToLoad << 3), CRegName::GPR_Lo[MipsRegToLoad]);
SetArmRegProtected(GprReg, false);
}
else if (IsMapped(MipsRegToLoad))
@ -405,40 +409,40 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
{
if (IsSigned(MipsRegToLoad))
{
ShiftRightSignImmed(regHi, GetMipsRegMapLo(MipsRegToLoad), 31);
m_Assembler.ShiftRightSignImmed(regHi, GetMipsRegMapLo(MipsRegToLoad), 31);
}
else
{
MoveConstToArmReg(regHi, (uint32_t)0);
m_Assembler.MoveConstToArmReg(regHi, (uint32_t)0);
}
if (MipsReg != MipsRegToLoad)
{
AddConstToArmReg(reglo, GetMipsRegMapLo(MipsRegToLoad), 0);
m_Assembler.AddConstToArmReg(reglo, GetMipsRegMapLo(MipsRegToLoad), 0);
}
}
else if (MipsReg != MipsRegToLoad)
{
AddConstToArmReg(regHi, GetMipsRegMapHi(MipsRegToLoad), 0);
AddConstToArmReg(reglo, GetMipsRegMapLo(MipsRegToLoad), 0);
m_Assembler.AddConstToArmReg(regHi, GetMipsRegMapHi(MipsRegToLoad), 0);
m_Assembler.AddConstToArmReg(reglo, GetMipsRegMapLo(MipsRegToLoad), 0);
}
}
else
{
if (Is32Bit(MipsRegToLoad))
{
MoveConstToArmReg(regHi, (uint32_t)(IsSigned(MipsRegToLoad) ? GetMipsRegLo_S(MipsRegToLoad) >> 31 : 0));
m_Assembler.MoveConstToArmReg(regHi, (uint32_t)(IsSigned(MipsRegToLoad) ? GetMipsRegLo_S(MipsRegToLoad) >> 31 : 0));
}
else
{
MoveConstToArmReg(regHi, GetMipsRegHi(MipsRegToLoad));
m_Assembler.MoveConstToArmReg(regHi, GetMipsRegHi(MipsRegToLoad));
}
MoveConstToArmReg(reglo, GetMipsRegLo(MipsRegToLoad));
m_Assembler.MoveConstToArmReg(reglo, GetMipsRegLo(MipsRegToLoad));
}
}
else if (MipsRegToLoad == 0)
{
MoveConstToArmReg(regHi, (uint32_t)0);
MoveConstToArmReg(reglo, (uint32_t)0);
m_Assembler.MoveConstToArmReg(regHi, (uint32_t)0);
m_Assembler.MoveConstToArmReg(reglo, (uint32_t)0);
}
SetArmRegMapped(regHi, GPR_Mapped);
SetArmRegMapped(reglo, GPR_Mapped);
@ -453,7 +457,7 @@ void CArmRegInfo::UnMap_GPR(uint32_t MipsReg, bool WriteBackValue)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -472,7 +476,7 @@ void CArmRegInfo::UnMap_GPR(uint32_t MipsReg, bool WriteBackValue)
}
if (IsUnknown(MipsReg)) { return; }
//CPU_Message("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,CRegName::GPR[Reg],WriteBackValue?"true":"false");
//m_CodeBlock.Log("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,CRegName::GPR[Reg],WriteBackValue?"true":"false");
if (IsConst(MipsReg))
{
SetMipsRegState(MipsReg, STATE_UNKNOWN);
@ -480,11 +484,11 @@ void CArmRegInfo::UnMap_GPR(uint32_t MipsReg, bool WriteBackValue)
}
if (Is64Bit(MipsReg))
{
CPU_Message(" regcache: unallocate %s from %s", ArmRegName(GetMipsRegMapHi(MipsReg)), CRegName::GPR_Hi[MipsReg]);
m_CodeBlock.Log(" regcache: unallocate %s from %s", m_Assembler.ArmRegName(GetMipsRegMapHi(MipsReg)), CRegName::GPR_Hi[MipsReg]);
SetArmRegMapped(GetMipsRegMapHi(MipsReg), NotMapped);
SetArmRegProtected(GetMipsRegMapHi(MipsReg), false);
}
CPU_Message(" regcache: unallocate %s from %s", ArmRegName(GetMipsRegMapLo(MipsReg)), CRegName::GPR_Lo[MipsReg]);
m_CodeBlock.Log(" regcache: unallocate %s from %s", m_Assembler.ArmRegName(GetMipsRegMapLo(MipsReg)), CRegName::GPR_Lo[MipsReg]);
SetArmRegMapped(GetMipsRegMapLo(MipsReg), NotMapped);
SetArmRegProtected(GetMipsRegMapLo(MipsReg), false);
SetMipsRegState(MipsReg, STATE_UNKNOWN);
@ -494,7 +498,7 @@ void CArmRegInfo::WriteBack_GPR(uint32_t MipsReg, bool Unmapping)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -512,31 +516,31 @@ void CArmRegInfo::WriteBack_GPR(uint32_t MipsReg, bool Unmapping)
return;
}
ArmReg GprReg = Map_Variable(VARIABLE_GPR);
CArmOps::ArmReg GprReg = Map_Variable(VARIABLE_GPR);
if (IsConst(MipsReg))
{
ArmReg TempReg = m_RegWorkingSet.Map_TempReg(Arm_Any, -1, false);
CArmOps::ArmReg TempReg = Map_TempReg(CArmOps::Arm_Any, -1, false);
if (Is64Bit(MipsReg))
{
MoveConstToArmReg(TempReg, GetMipsRegHi(MipsReg));
StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
m_Assembler.MoveConstToArmReg(TempReg, GetMipsRegHi(MipsReg));
m_Assembler.StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
}
else if (!g_System->b32BitCore())
{
MoveConstToArmReg(TempReg, (GetMipsRegLo(MipsReg) & 0x80000000) != 0 ? 0xFFFFFFFF : 0);
StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
m_Assembler.MoveConstToArmReg(TempReg, (GetMipsRegLo(MipsReg) & 0x80000000) != 0 ? 0xFFFFFFFF : 0);
m_Assembler.StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
}
MoveConstToArmReg(TempReg, GetMipsRegLo(MipsReg));
StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3), CRegName::GPR_Lo[MipsReg]);
m_RegWorkingSet.SetArmRegProtected(TempReg, false);
m_Assembler.MoveConstToArmReg(TempReg, GetMipsRegLo(MipsReg));
m_Assembler.StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3), CRegName::GPR_Lo[MipsReg]);
SetArmRegProtected(TempReg, false);
}
else
{
StoreArmRegToArmRegPointer(GetMipsRegMapLo(MipsReg), GprReg, (uint8_t)(MipsReg << 3), CRegName::GPR_Lo[MipsReg]);
m_Assembler.StoreArmRegToArmRegPointer(GetMipsRegMapLo(MipsReg), GprReg, (uint8_t)(MipsReg << 3), CRegName::GPR_Lo[MipsReg]);
if (Is64Bit(MipsReg))
{
StoreArmRegToArmRegPointer(GetMipsRegMapHi(MipsReg), GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
m_Assembler.StoreArmRegToArmRegPointer(GetMipsRegMapHi(MipsReg), GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
}
else if (!g_System->b32BitCore())
{
@ -544,24 +548,24 @@ void CArmRegInfo::WriteBack_GPR(uint32_t MipsReg, bool Unmapping)
if (!Unmapping)
{
SetArmRegProtected(GetMipsRegMapLo(MipsReg), true);
ArmReg TempReg = m_RegWorkingSet.Map_TempReg(Arm_Any, -1, false);
CArmOps::ArmReg TempReg = Map_TempReg(CArmOps::Arm_Any, -1, false);
if (IsSigned(MipsReg))
{
ShiftRightSignImmed(TempReg, GetMipsRegMapLo(MipsReg), 31);
m_Assembler.ShiftRightSignImmed(TempReg, GetMipsRegMapLo(MipsReg), 31);
}
else
{
MoveConstToArmReg(TempReg, (uint32_t)0);
m_Assembler.MoveConstToArmReg(TempReg, (uint32_t)0);
}
StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
m_RegWorkingSet.SetArmRegProtected(TempReg, false);
m_Assembler.StoreArmRegToArmRegPointer(TempReg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
SetArmRegProtected(TempReg, false);
}
else
{
ShiftRightSignImmed(GetMipsRegMapLo(MipsReg), GetMipsRegMapLo(MipsReg), 31);
StoreArmRegToArmRegPointer(GetMipsRegMapLo(MipsReg), GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
m_Assembler.ShiftRightSignImmed(GetMipsRegMapLo(MipsReg), GetMipsRegMapLo(MipsReg), 31);
m_Assembler.StoreArmRegToArmRegPointer(GetMipsRegMapLo(MipsReg), GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
}
m_RegWorkingSet.SetArmRegProtected(GetMipsRegMapLo(MipsReg), loProtected);
SetArmRegProtected(GetMipsRegMapLo(MipsReg), loProtected);
}
}
SetArmRegProtected(GprReg, false);
@ -571,7 +575,7 @@ void CArmRegInfo::WriteBackRegisters()
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -579,8 +583,8 @@ void CArmRegInfo::WriteBackRegisters()
int32_t ArmRegCount = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]);
for (int32_t i = 1; i < 32; i++) { UnMap_GPR(i, true); }
for (int32_t i = 0; i < ArmRegCount; i++) { UnMap_ArmReg((ArmReg)i); }
for (int32_t i = 0; i < ArmRegCount; i++) { SetArmRegProtected((ArmReg)i, false); }
for (int32_t i = 0; i < ArmRegCount; i++) { UnMap_ArmReg((CArmOps::ArmReg)i); }
for (int32_t i = 0; i < ArmRegCount; i++) { SetArmRegProtected((CArmOps::ArmReg)i, false); }
for (int32_t count = 1; count < 32; count++)
{
@ -597,7 +601,7 @@ void CArmRegInfo::WriteBackRegisters()
g_Notify->BreakPoint(__FILE__, __LINE__);
break;
default:
CPU_Message("%s: Unknown state: %d reg %d (%s)", __FUNCTION__, GetMipsRegState(count), count, CRegName::GPR[count]);
m_CodeBlock.Log("%s: Unknown state: %d reg %d (%s)", __FUNCTION__, GetMipsRegState(count), count, CRegName::GPR[count]);
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
@ -607,61 +611,61 @@ void CArmRegInfo::UnMap_AllFPRs()
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CPU_Message("%s", __FUNCTION__);
m_CodeBlock.Log("%s", __FUNCTION__);
}
CArmOps::ArmReg CArmRegInfo::UnMap_TempReg(bool TempMapping)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
ArmReg Reg = Arm_Unknown;
CArmOps::ArmReg Reg = CArmOps::Arm_Unknown;
if (GetArmRegMapped(Arm_R7) == Temp_Mapped && !GetArmRegProtected(Arm_R7)) { return Arm_R7; }
if (GetArmRegMapped(Arm_R6) == Temp_Mapped && !GetArmRegProtected(Arm_R6)) { return Arm_R6; }
if (GetArmRegMapped(Arm_R5) == Temp_Mapped && !GetArmRegProtected(Arm_R5)) { return Arm_R5; }
if (GetArmRegMapped(Arm_R4) == Temp_Mapped && !GetArmRegProtected(Arm_R4)) { return Arm_R4; }
if (GetArmRegMapped(Arm_R3) == Temp_Mapped && !GetArmRegProtected(Arm_R3)) { return Arm_R3; }
if (GetArmRegMapped(Arm_R2) == Temp_Mapped && !GetArmRegProtected(Arm_R2)) { return Arm_R2; }
if (GetArmRegMapped(Arm_R1) == Temp_Mapped && !GetArmRegProtected(Arm_R1)) { return Arm_R1; }
if (GetArmRegMapped(Arm_R0) == Temp_Mapped && !GetArmRegProtected(Arm_R0)) { return Arm_R0; }
if (GetArmRegMapped( CArmOps::Arm_R7) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R7)) { return CArmOps::Arm_R7; }
if (GetArmRegMapped( CArmOps::Arm_R6) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R6)) { return CArmOps::Arm_R6; }
if (GetArmRegMapped( CArmOps::Arm_R5) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R5)) { return CArmOps::Arm_R5; }
if (GetArmRegMapped( CArmOps::Arm_R4) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R4)) { return CArmOps::Arm_R4; }
if (GetArmRegMapped( CArmOps::Arm_R3) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R3)) { return CArmOps::Arm_R3; }
if (GetArmRegMapped( CArmOps::Arm_R2) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R2)) { return CArmOps::Arm_R2; }
if (GetArmRegMapped( CArmOps::Arm_R1) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R1)) { return CArmOps::Arm_R1; }
if (GetArmRegMapped( CArmOps::Arm_R0) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R0)) { return CArmOps::Arm_R0; }
if (TempMapping)
{
if (GetArmRegMapped(Arm_R11) == Temp_Mapped && !GetArmRegProtected(Arm_R11)) { return Arm_R11; }
if (GetArmRegMapped(Arm_R10) == Temp_Mapped && !GetArmRegProtected(Arm_R10)) { return Arm_R10; }
if (GetArmRegMapped( CArmOps::Arm_R11) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R11)) { return CArmOps::Arm_R11; }
if (GetArmRegMapped( CArmOps::Arm_R10) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R10)) { return CArmOps::Arm_R10; }
}
if (GetArmRegMapped(Arm_R9) == Temp_Mapped && !GetArmRegProtected(Arm_R9)) { return Arm_R9; }
if (GetArmRegMapped(Arm_R8) == Temp_Mapped && !GetArmRegProtected(Arm_R8)) { return Arm_R8; }
if (GetArmRegMapped( CArmOps::Arm_R9) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R9)) { return CArmOps::Arm_R9; }
if (GetArmRegMapped( CArmOps::Arm_R8) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R8)) { return CArmOps::Arm_R8; }
if (Reg != Arm_Unknown)
if (Reg != CArmOps::Arm_Unknown)
{
if (GetArmRegMapped(Reg) == Temp_Mapped)
{
CPU_Message(" regcache: unallocate %s from temp storage", ArmRegName(Reg));
m_CodeBlock.Log(" regcache: unallocate %s from temp storage", m_Assembler.ArmRegName(Reg));
}
SetArmRegMapped(Reg, NotMapped);
}
return Reg;
}
bool CArmRegInfo::UnMap_ArmReg(ArmReg Reg)
bool CArmRegInfo::UnMap_ArmReg(CArmOps::ArmReg Reg)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return false;
}
if (GetArmRegProtected(Reg))
{
CPU_Message("%s: %s is protected", __FUNCTION__, ArmRegName(Reg));
m_CodeBlock.Log("%s: %s is protected", __FUNCTION__, m_Assembler.ArmRegName(Reg));
g_Notify->BreakPoint(__FILE__, __LINE__);
return false;
}
@ -701,13 +705,13 @@ bool CArmRegInfo::UnMap_ArmReg(ArmReg Reg)
}
else if (GetArmRegMapped(Reg) == Temp_Mapped)
{
CPU_Message(" regcache: unallocate %s from temporary storage", ArmRegName(Reg));
m_CodeBlock.Log(" regcache: unallocate %s from temporary storage", m_Assembler.ArmRegName(Reg));
SetArmRegMapped(Reg, NotMapped);
return true;
}
else if (GetArmRegMapped(Reg) == Variable_Mapped)
{
CPU_Message(" regcache: unallocate %s from variable mapping (%s)", ArmRegName(Reg), VariableMapName(GetVariableMappedTo(Reg)));
m_CodeBlock.Log(" regcache: unallocate %s from variable mapping (%s)", m_Assembler.ArmRegName(Reg), VariableMapName(GetVariableMappedTo(Reg)));
SetArmRegMapped(Reg, NotMapped);
m_Variable_MappedTo[Reg] = VARIABLE_UNKNOWN;
return true;
@ -720,13 +724,13 @@ void CArmRegInfo::ResetRegProtection()
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
for (uint32_t i = 0, n = sizeof(m_ArmReg_Protected) / sizeof(m_ArmReg_Protected[0]); i < n; i++)
{
SetArmRegProtected((ArmReg)i, false);
SetArmRegProtected((CArmOps::ArmReg)i, false);
}
}
@ -734,38 +738,38 @@ CArmOps::ArmReg CArmRegInfo::FreeArmReg(bool TempMapping)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
if ((GetArmRegMapped(Arm_R7) == NotMapped || GetArmRegMapped(Arm_R7) == Temp_Mapped) && !GetArmRegProtected(Arm_R7)) { return Arm_R7; }
if ((GetArmRegMapped(Arm_R6) == NotMapped || GetArmRegMapped(Arm_R6) == Temp_Mapped) && !GetArmRegProtected(Arm_R6)) { return Arm_R6; }
if ((GetArmRegMapped(Arm_R5) == NotMapped || GetArmRegMapped(Arm_R5) == Temp_Mapped) && !GetArmRegProtected(Arm_R5)) { return Arm_R5; }
if ((GetArmRegMapped(Arm_R4) == NotMapped || GetArmRegMapped(Arm_R4) == Temp_Mapped) && !GetArmRegProtected(Arm_R4)) { return Arm_R4; }
if ((GetArmRegMapped(Arm_R3) == NotMapped || GetArmRegMapped(Arm_R3) == Temp_Mapped) && !GetArmRegProtected(Arm_R3)) { return Arm_R3; }
if ((GetArmRegMapped(Arm_R2) == NotMapped || GetArmRegMapped(Arm_R2) == Temp_Mapped) && !GetArmRegProtected(Arm_R2)) { return Arm_R2; }
if ((GetArmRegMapped(Arm_R1) == NotMapped || GetArmRegMapped(Arm_R1) == Temp_Mapped) && !GetArmRegProtected(Arm_R1)) { return Arm_R1; }
if ((GetArmRegMapped(Arm_R0) == NotMapped || GetArmRegMapped(Arm_R0) == Temp_Mapped) && !GetArmRegProtected(Arm_R0)) { return Arm_R0; }
if ((GetArmRegMapped( CArmOps::Arm_R7) == NotMapped || GetArmRegMapped( CArmOps::Arm_R7) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R7)) { return CArmOps::Arm_R7; }
if ((GetArmRegMapped( CArmOps::Arm_R6) == NotMapped || GetArmRegMapped( CArmOps::Arm_R6) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R6)) { return CArmOps::Arm_R6; }
if ((GetArmRegMapped( CArmOps::Arm_R5) == NotMapped || GetArmRegMapped( CArmOps::Arm_R5) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R5)) { return CArmOps::Arm_R5; }
if ((GetArmRegMapped( CArmOps::Arm_R4) == NotMapped || GetArmRegMapped( CArmOps::Arm_R4) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R4)) { return CArmOps::Arm_R4; }
if ((GetArmRegMapped( CArmOps::Arm_R3) == NotMapped || GetArmRegMapped( CArmOps::Arm_R3) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R3)) { return CArmOps::Arm_R3; }
if ((GetArmRegMapped( CArmOps::Arm_R2) == NotMapped || GetArmRegMapped( CArmOps::Arm_R2) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R2)) { return CArmOps::Arm_R2; }
if ((GetArmRegMapped( CArmOps::Arm_R1) == NotMapped || GetArmRegMapped( CArmOps::Arm_R1) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R1)) { return CArmOps::Arm_R1; }
if ((GetArmRegMapped( CArmOps::Arm_R0) == NotMapped || GetArmRegMapped( CArmOps::Arm_R0) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R0)) { return CArmOps::Arm_R0; }
if (TempMapping)
{
if ((GetArmRegMapped(Arm_R11) == NotMapped || GetArmRegMapped(Arm_R11) == Temp_Mapped) && !GetArmRegProtected(Arm_R11)) { return Arm_R11; }
if ((GetArmRegMapped(Arm_R10) == NotMapped || GetArmRegMapped(Arm_R10) == Temp_Mapped) && !GetArmRegProtected(Arm_R10)) { return Arm_R10; }
if ((GetArmRegMapped( CArmOps::Arm_R11) == NotMapped || GetArmRegMapped( CArmOps::Arm_R11) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R11)) { return CArmOps::Arm_R11; }
if ((GetArmRegMapped( CArmOps::Arm_R10) == NotMapped || GetArmRegMapped( CArmOps::Arm_R10) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R10)) { return CArmOps::Arm_R10; }
}
if ((GetArmRegMapped(Arm_R9) == NotMapped || GetArmRegMapped(Arm_R9) == Temp_Mapped) && !GetArmRegProtected(Arm_R9)) { return Arm_R9; }
if ((GetArmRegMapped(Arm_R8) == NotMapped || GetArmRegMapped(Arm_R8) == Temp_Mapped) && !GetArmRegProtected(Arm_R8)) { return Arm_R8; }
if ((GetArmRegMapped( CArmOps::Arm_R9) == NotMapped || GetArmRegMapped( CArmOps::Arm_R9) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R9)) { return CArmOps::Arm_R9; }
if ((GetArmRegMapped( CArmOps::Arm_R8) == NotMapped || GetArmRegMapped( CArmOps::Arm_R8) == Temp_Mapped) && !GetArmRegProtected( CArmOps::Arm_R8)) { return CArmOps::Arm_R8; }
ArmReg Reg = UnMap_TempReg(TempMapping);
if (Reg != Arm_Unknown) { return Reg; }
CArmOps::ArmReg Reg = UnMap_TempReg(TempMapping);
if (Reg != CArmOps::Arm_Unknown) { return Reg; }
int32_t MapCount[Arm_R12];
ArmReg MapReg[Arm_R12];
int32_t MapCount[ CArmOps::Arm_R12];
CArmOps::ArmReg MapReg[ CArmOps::Arm_R12];
for (int32_t i = 0, n = TempMapping ? Arm_R12 : Arm_R10; i < n; i++)
for (int32_t i = 0, n = TempMapping ? CArmOps::Arm_R12 : CArmOps::Arm_R10; i < n; i++)
{
MapCount[i] = GetArmRegMapOrder((ArmReg)i);
MapReg[i] = (ArmReg)i;
MapCount[i] = GetArmRegMapOrder((CArmOps::ArmReg)i);
MapReg[i] = (CArmOps::ArmReg)i;
}
for (int32_t i = 0, n = TempMapping ? Arm_R12 : Arm_R10; i < n; i++)
for (int32_t i = 0, n = TempMapping ? CArmOps::Arm_R12 : CArmOps::Arm_R10; i < n; i++)
{
bool changed = false;
for (int32_t z = 0; z < n - 1; z++)
@ -777,7 +781,7 @@ CArmOps::ArmReg CArmRegInfo::FreeArmReg(bool TempMapping)
uint32_t temp = MapCount[z];
MapCount[z] = MapCount[z + 1];
MapCount[z + 1] = temp;
ArmReg tempReg = MapReg[z];
CArmOps::ArmReg tempReg = MapReg[z];
MapReg[z] = MapReg[z + 1];
MapReg[z + 1] = tempReg;
changed = true;
@ -788,20 +792,20 @@ CArmOps::ArmReg CArmRegInfo::FreeArmReg(bool TempMapping)
}
}
for (int32_t i = 0, n = TempMapping ? Arm_R12 : Arm_R10; i < n; i++)
for (int32_t i = 0, n = TempMapping ? CArmOps::Arm_R12 : CArmOps::Arm_R10; i < n; i++)
{
if (((MapCount[i] > 0 && GetArmRegMapped(MapReg[i]) == GPR_Mapped) || GetArmRegMapped(MapReg[i]) == Variable_Mapped) && !GetArmRegProtected((ArmReg)MapReg[i]))
if (((MapCount[i] > 0 && GetArmRegMapped(MapReg[i]) == GPR_Mapped) || GetArmRegMapped(MapReg[i]) == Variable_Mapped) && !GetArmRegProtected((CArmOps::ArmReg)MapReg[i]))
{
if (UnMap_ArmReg((ArmReg)MapReg[i]))
if (UnMap_ArmReg((CArmOps::ArmReg)MapReg[i]))
{
return (ArmReg)MapReg[i];
return (CArmOps::ArmReg)MapReg[i];
}
}
}
LogRegisterState();
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
void CArmRegInfo::LogRegisterState(void)
@ -815,7 +819,7 @@ void CArmRegInfo::LogRegisterState(void)
{
stdstr regname;
if (GetArmRegMapped((ArmReg)i) == CArmRegInfo::GPR_Mapped)
if (GetArmRegMapped((CArmOps::ArmReg)i) == CArmRegInfo::GPR_Mapped)
{
for (uint32_t count = 1; count < 32; count++)
{
@ -824,12 +828,12 @@ void CArmRegInfo::LogRegisterState(void)
continue;
}
if (Is64Bit(count) && GetMipsRegMapHi(count) == (ArmReg)i)
if (Is64Bit(count) && GetMipsRegMapHi(count) == (CArmOps::ArmReg)i)
{
regname = CRegName::GPR_Hi[count];
break;
}
if (GetMipsRegMapLo(count) == (ArmReg)i)
if (GetMipsRegMapLo(count) == (CArmOps::ArmReg)i)
{
regname = CRegName::GPR_Lo[count];
break;
@ -837,50 +841,50 @@ void CArmRegInfo::LogRegisterState(void)
}
}
CPU_Message("GetArmRegMapped(%s) = %X%s%s Protected: %s MapOrder: %d",
ArmRegName((ArmReg)i),
GetArmRegMapped((ArmReg)i),
GetArmRegMapped((ArmReg)i) == CArmRegInfo::Variable_Mapped ? stdstr_f(" (%s)", CArmRegInfo::VariableMapName(GetVariableMappedTo((ArmReg)i))).c_str() : "",
m_CodeBlock.Log("GetArmRegMapped(%s) = %X%s%s Protected: %s MapOrder: %d",
m_Assembler.ArmRegName((CArmOps::ArmReg)i),
GetArmRegMapped((CArmOps::ArmReg)i),
GetArmRegMapped((CArmOps::ArmReg)i) == CArmRegInfo::Variable_Mapped ? stdstr_f(" (%s)", CArmRegInfo::VariableMapName(GetVariableMappedTo((CArmOps::ArmReg)i))).c_str() : "",
regname.length() > 0 ? stdstr_f(" (%s)", regname.c_str()).c_str() : "",
GetArmRegProtected((ArmReg)i) ? "true" : "false",
GetArmRegMapOrder((ArmReg)i)
GetArmRegProtected((CArmOps::ArmReg)i) ? "true" : "false",
GetArmRegMapOrder((CArmOps::ArmReg)i)
);
}
}
CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord)
CArmOps::ArmReg CArmRegInfo::Map_TempReg(CArmOps::ArmReg Reg, int32_t MipsReg, bool LoadHiWord)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
ArmReg GprReg = MipsReg >= 0 ? Map_Variable(VARIABLE_GPR) : Arm_Unknown;
CArmOps::ArmReg GprReg = MipsReg >= 0 ? Map_Variable(VARIABLE_GPR) : CArmOps::Arm_Unknown;
if (Reg == CArmOps::Arm_Any)
{
if (GetArmRegMapped(Arm_R7) == Temp_Mapped && !GetArmRegProtected(Arm_R7)) { Reg = Arm_R7; }
else if (GetArmRegMapped(Arm_R6) == Temp_Mapped && !GetArmRegProtected(Arm_R6)) { Reg = Arm_R6; }
else if (GetArmRegMapped(Arm_R5) == Temp_Mapped && !GetArmRegProtected(Arm_R5)) { Reg = Arm_R5; }
else if (GetArmRegMapped(Arm_R4) == Temp_Mapped && !GetArmRegProtected(Arm_R4)) { Reg = Arm_R4; }
else if (GetArmRegMapped(Arm_R3) == Temp_Mapped && !GetArmRegProtected(Arm_R3)) { Reg = Arm_R3; }
else if (GetArmRegMapped(Arm_R2) == Temp_Mapped && !GetArmRegProtected(Arm_R2)) { Reg = Arm_R2; }
else if (GetArmRegMapped(Arm_R1) == Temp_Mapped && !GetArmRegProtected(Arm_R1)) { Reg = Arm_R1; }
else if (GetArmRegMapped(Arm_R0) == Temp_Mapped && !GetArmRegProtected(Arm_R0)) { Reg = Arm_R0; }
else if (GetArmRegMapped(Arm_R11) == Temp_Mapped && !GetArmRegProtected(Arm_R11)) { Reg = Arm_R11; }
else if (GetArmRegMapped(Arm_R10) == Temp_Mapped && !GetArmRegProtected(Arm_R10)) { Reg = Arm_R10; }
else if (GetArmRegMapped(Arm_R9) == Temp_Mapped && !GetArmRegProtected(Arm_R9)) { Reg = Arm_R9; }
else if (GetArmRegMapped(Arm_R8) == Temp_Mapped && !GetArmRegProtected(Arm_R8)) { Reg = Arm_R8; }
if (GetArmRegMapped( CArmOps::Arm_R7) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R7)) { Reg = CArmOps::Arm_R7; }
else if (GetArmRegMapped( CArmOps::Arm_R6) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R6)) { Reg = CArmOps::Arm_R6; }
else if (GetArmRegMapped( CArmOps::Arm_R5) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R5)) { Reg = CArmOps::Arm_R5; }
else if (GetArmRegMapped( CArmOps::Arm_R4) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R4)) { Reg = CArmOps::Arm_R4; }
else if (GetArmRegMapped( CArmOps::Arm_R3) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R3)) { Reg = CArmOps::Arm_R3; }
else if (GetArmRegMapped( CArmOps::Arm_R2) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R2)) { Reg = CArmOps::Arm_R2; }
else if (GetArmRegMapped( CArmOps::Arm_R1) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R1)) { Reg = CArmOps::Arm_R1; }
else if (GetArmRegMapped( CArmOps::Arm_R0) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R0)) { Reg = CArmOps::Arm_R0; }
else if (GetArmRegMapped( CArmOps::Arm_R11) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R11)) { Reg = CArmOps::Arm_R11; }
else if (GetArmRegMapped( CArmOps::Arm_R10) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R10)) { Reg = CArmOps::Arm_R10; }
else if (GetArmRegMapped( CArmOps::Arm_R9) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R9)) { Reg = CArmOps::Arm_R9; }
else if (GetArmRegMapped( CArmOps::Arm_R8) == Temp_Mapped && !GetArmRegProtected( CArmOps::Arm_R8)) { Reg = CArmOps::Arm_R8; }
if (Reg == Arm_Any)
if (Reg == CArmOps::Arm_Any)
{
Reg = FreeArmReg(true);
if (Reg == Arm_Unknown)
if (Reg == CArmOps::Arm_Unknown)
{
WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free register");
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
}
}
@ -901,12 +905,12 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
}
if (MipsReg < 0)
{
CPU_Message(" regcache: allocate %s as temporary storage", ArmRegName(Reg));
m_CodeBlock.Log(" regcache: allocate %s as temporary storage", m_Assembler.ArmRegName(Reg));
}
else
{
CPU_Message(" regcache: allocate %s as temporary storage (%s)", ArmRegName(Reg), LoadHiWord ? CRegName::GPR_Hi[MipsReg] : CRegName::GPR_Lo[MipsReg]);
if (GprReg == Arm_Unknown)
m_CodeBlock.Log(" regcache: allocate %s as temporary storage (%s)", m_Assembler.ArmRegName(Reg), LoadHiWord ? CRegName::GPR_Hi[MipsReg] : CRegName::GPR_Lo[MipsReg]);
if (GprReg == CArmOps::Arm_Unknown)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
@ -914,7 +918,7 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
{
if (IsUnknown(MipsReg))
{
LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
m_Assembler.LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsReg << 3) + 4, CRegName::GPR_Hi[MipsReg]);
}
else if (IsMapped(MipsReg))
{
@ -925,11 +929,11 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
}
else if (IsSigned(MipsReg))
{
ShiftRightSignImmed(Reg, GetMipsRegMapLo(MipsReg), 31);
m_Assembler.ShiftRightSignImmed(Reg, GetMipsRegMapLo(MipsReg), 31);
}
else
{
MoveConstToArmReg(Reg, (uint32_t)0);
m_Assembler.MoveConstToArmReg(Reg, (uint32_t)0);
}
}
else
@ -937,12 +941,12 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
if (Is64Bit(MipsReg))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
//MoveConstToArmReg(Reg, GetMipsRegHi(MipsReg));
//m_Assembler.MoveConstToArmReg(Reg, GetMipsRegHi(MipsReg));
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
//MoveConstToArmReg(Reg, GetMipsRegLo_S(MipsReg) >> 31);
//m_Assembler.MoveConstToArmReg(Reg, GetMipsRegLo_S(MipsReg) >> 31);
}
}
}
@ -950,15 +954,15 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
{
if (IsUnknown(MipsReg))
{
LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsReg << 3), CRegName::GPR_Lo[MipsReg]);
m_Assembler.LoadArmRegPointerToArmReg(Reg, GprReg, (uint8_t)(MipsReg << 3), CRegName::GPR_Lo[MipsReg]);
}
else if (IsMapped(MipsReg))
{
AddConstToArmReg(Reg, GetMipsRegMapLo(MipsReg), 0);
m_Assembler.AddConstToArmReg(Reg, GetMipsRegMapLo(MipsReg), 0);
}
else
{
MoveConstToArmReg(Reg, GetMipsRegLo(MipsReg));
m_Assembler.MoveConstToArmReg(Reg, GetMipsRegLo(MipsReg));
}
}
}
@ -966,10 +970,10 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
SetArmRegProtected(Reg, true);
for (int32_t i = 0, n = sizeof(m_ArmReg_MappedTo) / sizeof(m_ArmReg_MappedTo[0]); i < n; i++)
{
int32_t MapOrder = GetArmRegMapOrder((ArmReg)i);
int32_t MapOrder = GetArmRegMapOrder((CArmOps::ArmReg)i);
if (MapOrder > 0)
{
SetArmRegMapOrder((ArmReg)i, MapOrder + 1);
SetArmRegMapOrder((CArmOps::ArmReg)i, MapOrder + 1);
}
}
SetArmRegMapOrder(Reg, 1);
@ -977,44 +981,44 @@ CArmOps::ArmReg CArmRegInfo::Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadH
return Reg;
}
CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable, ArmReg Reg)
CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable, CArmOps::ArmReg Reg)
{
CPU_Message("%s: variable: %s Reg: %d", __FUNCTION__, VariableMapName(variable), Reg);
m_CodeBlock.Log("%s: variable: %s Reg: %d", __FUNCTION__, VariableMapName(variable), Reg);
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
if (Reg == Arm_Unknown)
if (Reg == CArmOps::Arm_Unknown)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
if (variable == VARIABLE_GPR && Reg != Arm_Any && Reg != Arm_R12)
if (variable == VARIABLE_GPR && Reg != CArmOps::Arm_Any && Reg != CArmOps::Arm_R12)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
if (Reg == Arm_Any)
if (Reg == CArmOps::Arm_Any)
{
Reg = GetVariableReg(variable);
if (Reg != Arm_Unknown)
if (Reg != CArmOps::Arm_Unknown)
{
SetArmRegProtected(Reg, true);
return Reg;
}
Reg = variable == VARIABLE_GPR ? Arm_R12 : FreeArmReg(false);
if (Reg == Arm_Unknown)
Reg = variable == VARIABLE_GPR ? CArmOps::Arm_R12 : FreeArmReg(false);
if (Reg == CArmOps::Arm_Unknown)
{
WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free register");
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
}
else if (GetArmRegMapped(Reg) == Variable_Mapped && m_Variable_MappedTo[Reg] == variable)
@ -1029,19 +1033,19 @@ CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable, ArmReg Reg)
SetArmRegMapped(Reg, Variable_Mapped);
SetArmRegProtected(Reg, true);
CPU_Message(" regcache: allocate %s as pointer to %s", ArmRegName(Reg), VariableMapName(variable));
m_CodeBlock.Log(" regcache: allocate %s as pointer to %s", m_Assembler.ArmRegName(Reg), VariableMapName(variable));
m_Variable_MappedTo[Reg] = variable;
if (variable == VARIABLE_GPR) { MoveConstToArmReg(Reg, (uint32_t)_GPR, "_GPR"); }
else if (variable == VARIABLE_FPR) { MoveConstToArmReg(Reg, (uint32_t)_FPR_S, "_FPR_S"); }
else if (variable == VARIABLE_TLB_READMAP) { MoveConstToArmReg(Reg, (uint32_t)(g_MMU->m_TLB_ReadMap), "MMU->TLB_ReadMap"); }
else if (variable == VARIABLE_TLB_WRITEMAP) { MoveConstToArmReg(Reg, (uint32_t)(g_MMU->m_TLB_WriteMap), "MMU->m_TLB_WriteMap"); }
else if (variable == VARIABLE_TLB_LOAD_ADDRESS) { MoveConstToArmReg(Reg, (uint32_t)(g_TLBLoadAddress), "g_TLBLoadAddress"); }
else if (variable == VARIABLE_TLB_STORE_ADDRESS) { MoveConstToArmReg(Reg, (uint32_t)(g_TLBStoreAddress), "g_TLBStoreAddress"); }
else if (variable == VARIABLE_NEXT_TIMER) { MoveConstToArmReg(Reg, (uint32_t)(g_NextTimer), "g_NextTimer"); }
if (variable == VARIABLE_GPR) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)_GPR, "_GPR"); }
else if (variable == VARIABLE_FPR) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)_FPR_S, "_FPR_S"); }
else if (variable == VARIABLE_TLB_READMAP) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)(g_MMU->m_TLB_ReadMap), "MMU->TLB_ReadMap"); }
else if (variable == VARIABLE_TLB_WRITEMAP) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)(g_MMU->m_TLB_WriteMap), "MMU->m_TLB_WriteMap"); }
else if (variable == VARIABLE_TLB_LOAD_ADDRESS) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)(g_TLBLoadAddress), "g_TLBLoadAddress"); }
else if (variable == VARIABLE_TLB_STORE_ADDRESS) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)(g_TLBStoreAddress), "g_TLBStoreAddress"); }
else if (variable == VARIABLE_NEXT_TIMER) { m_Assembler.MoveConstToArmReg(Reg, (uint32_t)(g_NextTimer), "g_NextTimer"); }
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
return Reg;
}
@ -1052,17 +1056,17 @@ CArmOps::ArmReg CArmRegInfo::GetVariableReg(VARIABLE_MAPPED variable) const
{
if (m_ArmReg_MappedTo[i] == Variable_Mapped && m_Variable_MappedTo[i] == variable)
{
return (ArmReg)i;
return (CArmOps::ArmReg)i;
}
}
return Arm_Unknown;
return CArmOps::Arm_Unknown;
}
void CArmRegInfo::ProtectGPR(uint32_t Reg)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
@ -1081,7 +1085,7 @@ void CArmRegInfo::UnProtectGPR(uint32_t Reg)
{
if (m_InCallDirect)
{
CPU_Message("%s: in CallDirect", __FUNCTION__);
m_CodeBlock.Log("%s: in CallDirect", __FUNCTION__);
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}

View File

@ -6,7 +6,7 @@
class CArmRegInfo :
public CRegBase,
public CArmOps,
private CDebugSettings,
private CSystemRegisters
{
public:
@ -31,7 +31,7 @@ public:
VARIABLE_NEXT_TIMER = 7,
};
CArmRegInfo();
CArmRegInfo(CCodeBlock & CodeBlock, CArmOps & Assembler);
CArmRegInfo(const CArmRegInfo&);
~CArmRegInfo();
@ -46,45 +46,50 @@ public:
void FixRoundModel(FPU_ROUND RoundMethod);
void Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsRegToLoad);
void Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad);
ArmReg FreeArmReg(bool TempMapping);
CArmOps::ArmReg FreeArmReg(bool TempMapping);
void WriteBackRegisters();
ArmReg Map_TempReg(ArmReg Reg, int32_t MipsReg, bool LoadHiWord);
ArmReg Map_Variable(VARIABLE_MAPPED variable, ArmReg Reg = Arm_Any);
ArmReg GetVariableReg(VARIABLE_MAPPED variable) const;
CArmOps::ArmReg Map_TempReg(CArmOps::ArmReg Reg, int32_t MipsReg, bool LoadHiWord);
CArmOps::ArmReg Map_Variable(VARIABLE_MAPPED variable, CArmOps::ArmReg Reg = CArmOps::Arm_Any);
CArmOps::ArmReg GetVariableReg(VARIABLE_MAPPED variable) const;
void ProtectGPR(uint32_t Reg);
void UnProtectGPR(uint32_t Reg);
void UnMap_AllFPRs();
ArmReg UnMap_TempReg(bool TempMapping);
CArmOps::ArmReg UnMap_TempReg(bool TempMapping);
void UnMap_GPR(uint32_t Reg, bool WriteBackValue);
void WriteBack_GPR(uint32_t MipsReg, bool Unmapping);
bool UnMap_ArmReg(ArmReg Reg);
bool UnMap_ArmReg(CArmOps::ArmReg Reg);
void ResetRegProtection();
inline ArmReg GetMipsRegMapLo(int32_t Reg) const { return m_RegMapLo[Reg]; }
inline ArmReg GetMipsRegMapHi(int32_t Reg) const { return m_RegMapHi[Reg]; }
inline void SetMipsRegMapLo(int32_t GetMipsReg, ArmReg Reg) { m_RegMapLo[GetMipsReg] = Reg; }
inline void SetMipsRegMapHi(int32_t GetMipsReg, ArmReg Reg) { m_RegMapHi[GetMipsReg] = Reg; }
inline CArmOps::ArmReg GetMipsRegMapLo(int32_t Reg) const { return m_RegMapLo[Reg]; }
inline CArmOps::ArmReg GetMipsRegMapHi(int32_t Reg) const { return m_RegMapHi[Reg]; }
inline void SetMipsRegMapLo(int32_t GetMipsReg, CArmOps::ArmReg Reg) { m_RegMapLo[GetMipsReg] = Reg; }
inline void SetMipsRegMapHi(int32_t GetMipsReg, CArmOps::ArmReg Reg) { m_RegMapHi[GetMipsReg] = Reg; }
inline uint32_t GetArmRegMapOrder(ArmReg Reg) const { return m_ArmReg_MapOrder[Reg]; }
inline bool GetArmRegProtected(ArmReg Reg) const { return m_ArmReg_Protected[Reg]; }
inline REG_MAPPED GetArmRegMapped(ArmReg Reg) const { return m_ArmReg_MappedTo[Reg]; }
inline uint32_t GetArmRegMapOrder(CArmOps::ArmReg Reg) const { return m_ArmReg_MapOrder[Reg]; }
inline bool GetArmRegProtected(CArmOps::ArmReg Reg) const { return m_ArmReg_Protected[Reg]; }
inline REG_MAPPED GetArmRegMapped(CArmOps::ArmReg Reg) const { return m_ArmReg_MappedTo[Reg]; }
inline void SetArmRegMapOrder(ArmReg Reg, uint32_t Order) { m_ArmReg_MapOrder[Reg] = Order; }
inline void SetArmRegProtected(ArmReg Reg, bool Protected) { m_ArmReg_Protected[Reg] = Protected; }
inline void SetArmRegMapped(ArmReg Reg, REG_MAPPED Mapping) { m_ArmReg_MappedTo[Reg] = Mapping; }
inline void SetArmRegMapOrder(CArmOps::ArmReg Reg, uint32_t Order) { m_ArmReg_MapOrder[Reg] = Order; }
inline void SetArmRegProtected(CArmOps::ArmReg Reg, bool Protected) { m_ArmReg_Protected[Reg] = Protected; }
inline void SetArmRegMapped(CArmOps::ArmReg Reg, REG_MAPPED Mapping) { m_ArmReg_MappedTo[Reg] = Mapping; }
inline VARIABLE_MAPPED GetVariableMappedTo(ArmReg Reg) const { return m_Variable_MappedTo[Reg]; }
inline void SetVariableMappedTo(ArmReg Reg, VARIABLE_MAPPED variable) { m_Variable_MappedTo[Reg] = variable; }
inline VARIABLE_MAPPED GetVariableMappedTo(CArmOps::ArmReg Reg) const { return m_Variable_MappedTo[Reg]; }
inline void SetVariableMappedTo(CArmOps::ArmReg Reg, VARIABLE_MAPPED variable) { m_Variable_MappedTo[Reg] = variable; }
static const char * VariableMapName(VARIABLE_MAPPED variable);
void LogRegisterState(void);
private:
bool ShouldPushPopReg (ArmReg Reg);
CArmRegInfo();
ArmReg m_RegMapHi[32];
ArmReg m_RegMapLo[32];
CCodeBlock & m_CodeBlock;
CArmOps & m_Assembler;
bool ShouldPushPopReg (CArmOps::ArmReg Reg);
CArmOps::ArmReg m_RegMapHi[32];
CArmOps::ArmReg m_RegMapLo[32];
uint32_t m_ArmReg_MapOrder[16];
bool m_ArmReg_Protected[16];
REG_MAPPED m_ArmReg_MappedTo[16];

View File

@ -32,7 +32,7 @@ CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter, uint8_t * Compi
#if defined(__i386__) || defined(_M_IX86)
m_RecompilerOps = new CX86RecompilerOps(MMU, *this);
#elif defined(__arm__) || defined(_M_ARM)
m_RecompilerOps = new CArmRecompilerOps(MMU);
m_RecompilerOps = new CArmRecompilerOps(MMU, *this);
#else
g_Notify->BreakPoint(__FILE__, __LINE__);
#endif

View File

@ -3,6 +3,10 @@
#include <Project64-core/N64System/Recompiler/RecompilerOps.h>
#include <Project64-core/N64System/Recompiler/CodeSection.h>
#if !defined(_MSC_VER) && !defined(_Printf_format_string_)
#define _Printf_format_string_
#endif
class CMipsMemoryVM;
class CCodeBlock

View File

@ -46,6 +46,6 @@ typedef CX86RecompilerOps CRecompilerOps;
#elif defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h>
typedef CX86RecompilerOps CArmRecompilerOps;
typedef CArmRecompilerOps CRecompilerOps;
#endif

View File

@ -1,6 +1,10 @@
#pragma once
#if defined(__i386__) || defined(_M_IX86)
#if !defined(_MSC_VER) && !defined(_Printf_format_string_)
#define _Printf_format_string_
#endif
class CCodeBlock;
class CX86Ops