diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp index ef1fa7656..050e4f3cd 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp @@ -15,6 +15,9 @@ #include #include #include +#include + +CArmRegInfo CArmOps::m_RegWorkingSet; /************************************************************************** * Logging Functions * @@ -252,16 +255,41 @@ void CArmOps::MoveConstToArmRegTop(ArmReg DestReg, uint16_t Const, const char * AddCode32(op.Hex); } -void CArmOps::CompareArmRegToConst(ArmReg Reg, uint8_t value) +void CArmOps::CompareArmRegToConst(ArmReg Reg, uint32_t value) { - if (Reg > 0x7) { g_Notify->BreakPoint(__FILE__,__LINE__); return; } + if (Reg <= 0x7 && (value & 0xFFFFFF00) == 0) + { + CPU_Message(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value); + ArmThumbOpcode op = {0}; + op.Imm8.imm8 = value; + op.Imm8.rdn = Reg; + op.Imm8.opcode = 0x5; + AddCode16(op.Hex); + } + else if(CanThumbCompressConst(value)) + { + CPU_Message(" 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; + op.imm8_3_1.s = 1; + op.imm8_3_1.opcode = 0xD; + op.imm8_3_1.i = (CompressedValue >> 11) & 1; + op.imm8_3_1.opcode2 = 0x1E; - CPU_Message(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value); - ArmThumbOpcode op = {0}; - op.Imm8.imm8 = value; - op.Imm8.rdn = Reg; - op.Imm8.opcode = 0x5; - AddCode16(op.Hex); + op.imm8_3_1.imm8 = CompressedValue & 0xFF; + op.imm8_3_1.rd = 0xF; + op.imm8_3_1.imm3 = (CompressedValue >> 8) & 0x3; + op.imm8_3_1.opcode3 = 0; + AddCode32(op.Hex); + } + else + { + ArmReg TempReg = m_RegWorkingSet.Map_TempReg(Arm_Any, -1, false); + MoveConstToArmReg(TempReg,value); + CompareArmRegToArmReg(Reg, TempReg); + m_RegWorkingSet.SetArmRegProtected(TempReg,false); + } } void CArmOps::CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2) diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h index ed380476b..9ab1e5332 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h @@ -11,6 +11,8 @@ #pragma once #if defined(__arm__) || defined(_M_ARM) +class CArmRegInfo; + class CArmOps { public: @@ -142,7 +144,7 @@ protected: static void BranchLabel8(ArmBranchCompare CompareType, const char * Label); static void BranchLabel20(ArmBranchCompare CompareType, const char * Label); static void CallFunction(void * Function, const char * FunctionName); - static void CompareArmRegToConst(ArmReg Reg, uint8_t value); + static void CompareArmRegToConst(ArmReg Reg, uint32_t value); static void CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2); static void LoadArmRegPointerToArmReg(ArmReg DestReg, ArmReg RegPointer, uint8_t Offset); static void MoveArmRegArmReg(ArmReg DestReg, ArmReg SourceReg); @@ -171,6 +173,8 @@ protected: static void AddCode8(uint8_t value); static void AddCode16(uint16_t value); static void AddCode32(uint32_t value); + + static CArmRegInfo m_RegWorkingSet; }; #define AddressOf(Addr) CArmOps::GetAddressOf(5,(Addr))