From c93f7760ce185e7ba120a2fb51090ab3732e0807 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 14 Mar 2013 01:50:38 +0000 Subject: [PATCH] Really clean up all the emitter loadstores on ARM. If a ARM device supports VFPv4, then it supports IDIVA, so handle that in CPUDetect. --- Source/Core/Common/Src/ArmCPUDetect.cpp | 6 +- Source/Core/Common/Src/ArmEmitter.cpp | 92 +++---------------- Source/Core/Common/Src/ArmEmitter.h | 34 ++----- .../Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp | 4 +- 4 files changed, 28 insertions(+), 108 deletions(-) diff --git a/Source/Core/Common/Src/ArmCPUDetect.cpp b/Source/Core/Common/Src/ArmCPUDetect.cpp index 8b5cbf9b79..db1c967ec3 100644 --- a/Source/Core/Common/Src/ArmCPUDetect.cpp +++ b/Source/Core/Common/Src/ArmCPUDetect.cpp @@ -154,8 +154,10 @@ std::string CPUInfo::Summarize() if (bVFPv3) sum += ", VFPv3"; if (bTLS) sum += ", TLS"; if (bVFPv4) sum += ", VFPv4"; - if (bIDIVa) sum += ", IDIVa"; - if (bIDIVt) sum += ", IDIVt"; + // On some buggy kernels(Qualcomm) they show that they support VFPv4 but not IDIVa + // All VFPv4 CPUs will support IDIVa + if (bIDIVa || bVFPv4) sum += ", IDIVa"; + if (bIDIVt || bVFPv4) sum += ", IDIVt"; return sum; } diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp index 5519f2b4da..ac619c8989 100644 --- a/Source/Core/Common/Src/ArmEmitter.cpp +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -176,7 +176,7 @@ void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize) } else { // Use literal pool for ARMv6. AddNewLit(val); - LDRLIT(reg, 0, 0); // To be backpatched later + LDR(reg, _PC); // To be backpatched later } } } @@ -608,39 +608,6 @@ void ARMXEmitter::MRS (ARMReg dest) { Write32(condition | (16 << 20) | (15 << 16) | (dest << 12)); } - -void ARMXEmitter::WriteStoreOp(u32 op, ARMReg src, ARMReg dest, s16 op2) -{ - // Qualcomm chipsets get /really/ angry if you don't use index, even if the offset is zero. - // bool Index = op2 != 0 ? true : false; - bool Index = true; - bool Add = op2 >= 0 ? true : false; - u32 imm = abs(op2); - Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (src << 16) | (dest << 12) | imm); -} -void ARMXEmitter::STR (ARMReg result, ARMReg base, s16 op) { WriteStoreOp(0x40, base, result, op);} -void ARMXEmitter::STRH (ARMReg result, ARMReg base, Operand2 op) -{ - u8 Imm = op.Imm8(); - Write32(condition | (0x04 << 20) | (base << 16) | (result << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F)); -} -void ARMXEmitter::STRB (ARMReg result, ARMReg base, s16 op) { WriteStoreOp(0x44, base, result, op);} -void ARMXEmitter::STR (ARMReg result, ARMReg base, Operand2 op2, bool Index, bool Add) -{ - Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | op2.IMMSR()); -} -void ARMXEmitter::STR (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | offset); -} -void ARMXEmitter::STRH (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x00 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | (0xB << 4) | offset); -} -void ARMXEmitter::STRB (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x64 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (result << 12) | offset); -} void ARMXEmitter::LDREX(ARMReg dest, ARMReg base) { Write32(condition | (25 << 20) | (base << 16) | (dest << 12) | 0xF9F); @@ -681,7 +648,7 @@ const char *LoadStoreNames[] = { "STR", "LDRSH", }; -void ARMXEmitter::WriteNewStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 op2, bool RegAdd) +void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool RegAdd) { s32 op = LoadStoreOps[Op][Rm.GetType()]; // Type always decided by last operand u32 Data; @@ -726,12 +693,14 @@ void ARMXEmitter::WriteNewStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 op2, bo switch (Rm.GetType()) { case TYPE_IMM: + { s32 Temp = (s32)Rm.Value; Data = abs(Temp); // The offset is encoded differently on this one. if (SpecialOp) Data = (Data & 0xF0 << 4) | (Data & 0xF); - if (Temp >= 0) ImmAdd = true; + if (Temp >= 0) Add = true; + } break; case TYPE_REG: case TYPE_IMMSREG: @@ -756,49 +725,14 @@ void ARMXEmitter::WriteNewStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 op2, bo Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (Rn << 16) | (Rt << 12) | Data); } -void ARMXEmitter::LDR (ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x41, src, dest, op);} -void ARMXEmitter::LDRH(ARMReg dest, ARMReg src, Operand2 op) -{ - u8 Imm = op.Imm8(); - Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F)); -} -void ARMXEmitter::LDRSH(ARMReg dest, ARMReg src, Operand2 op) -{ - u8 Imm = op.Imm8(); - Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xF << 4) | (Imm & 0x0F)); -} -void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x45, src, dest, op);} -void ARMXEmitter::LDRSB(ARMReg dest, ARMReg src, Operand2 op) -{ - u8 Imm = op.Imm8(); - Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xD << 4) | (Imm & 0x0F)); -} - -void ARMXEmitter::LDR (ARMReg dest, ARMReg base, Operand2 op2, bool Index, bool Add) -{ - Write32(condition | (0x61 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | op2.IMMSR()); -} -void ARMXEmitter::LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x61 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset); -} -void ARMXEmitter::LDRH (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xB << 4) | offset); -} -void ARMXEmitter::LDRSH(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xF << 4) | offset); -} -void ARMXEmitter::LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x65 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset); -} -void ARMXEmitter::LDRSB(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) -{ - Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xD << 4) | offset); -} -void ARMXEmitter::LDRLIT (ARMReg dest, u32 offset, bool Add) { Write32(condition | 0x05 << 24 | Add << 23 | 0x1F << 16 | dest << 12 | offset);} +void ARMXEmitter::LDR (ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(1, dest, base, op2, RegAdd);} +void ARMXEmitter::LDRB(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(3, dest, base, op2, RegAdd);} +void ARMXEmitter::LDRH(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(5, dest, base, op2, RegAdd);} +void ARMXEmitter::LDRSB(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(6, dest, base, op2, RegAdd);} +void ARMXEmitter::LDRSH(ARMReg dest, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(7, dest, base, op2, RegAdd);} +void ARMXEmitter::STR (ARMReg result, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(0, result, base, op2, RegAdd);} +void ARMXEmitter::STRH (ARMReg result, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(4, result, base, op2, RegAdd);} +void ARMXEmitter::STRB (ARMReg result, ARMReg base, Operand2 op2, bool RegAdd) { WriteStoreOp(2, result, base, op2, RegAdd);} void ARMXEmitter::WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList) { diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h index 727626fa96..0749d42c96 100644 --- a/Source/Core/Common/Src/ArmEmitter.h +++ b/Source/Core/Common/Src/ArmEmitter.h @@ -352,9 +352,7 @@ private: u32 condition; std::vector currentLitPool; - void WriteStoreOp(u32 op, ARMReg src, ARMReg dest, s16 op2); - void WriteNewStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 op2, bool RegAdd); - + void WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 op2, bool RegAdd); void WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, ARMReg op2); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); @@ -497,28 +495,14 @@ public: void MRS (ARMReg dest); // Memory load/store operations - void LDR (ARMReg dest, ARMReg src, s16 op2 = 0); - void LDRH (ARMReg dest, ARMReg src, Operand2 op2 = 0); - void LDRSH(ARMReg dest, ARMReg src, Operand2 op2 = 0); - void LDRB (ARMReg dest, ARMReg src, s16 op2 = 0); - void LDRSB(ARMReg dest, ARMReg src, Operand2 op2 = 0); - // Offset adds to the base register in LDR - void LDR (ARMReg dest, ARMReg base, Operand2 op2, bool Index, bool Add); - void LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void LDRH (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void LDRSH(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void LDRSB(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void LDRLIT(ARMReg dest, u32 offset, bool Add); - - void STR (ARMReg result, ARMReg base, s16 op2 = 0); - void STRH (ARMReg result, ARMReg base, Operand2 op2 = 0); - void STRB (ARMReg result, ARMReg base, s16 op2 = 0); - // Offset adds on to the destination register in STR - void STR (ARMReg result, ARMReg base, Operand2 op2, bool Index, bool Add); - void STR (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add); - void STRH (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add); - void STRB (ARMReg result, ARMReg base, ARMReg offset, bool Index, bool Add); + void LDR (ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void LDRB (ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void LDRH (ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void LDRSB(ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void LDRSH(ARMReg dest, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void STR (ARMReg result, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void STRB (ARMReg result, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); + void STRH (ARMReg result, ARMReg base, Operand2 op2 = 0, bool RegAdd = true); void STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); void LDMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp index 28263baa32..aa999c9a39 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp @@ -72,7 +72,7 @@ void JitArmAsmRoutineManager::Generate() MOVI2R(R14, (u32)jit->GetBlockCache()->GetICache()); // Confirmed That this loads the base iCache Location correctly 08-04-12 - LDR(R12, R14, R12, true, true); // R12 contains iCache[PC & JIT_ICACHE_MASK] here + LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here // R12 Confirmed this is the correct iCache Location loaded. TST(R12, 0xFC); // Test to see if it is a JIT block. @@ -82,7 +82,7 @@ void JitArmAsmRoutineManager::Generate() // LDR R14 right here to get CodePointers()[0] pointer. REV(R12, R12); // Reversing this gives us our JITblock. LSL(R12, R12, 2); // Multiply by four because address locations are u32 in size - LDR(R14, R14, R12, true, true); // Load the block address in to R14 + LDR(R14, R14, R12); // Load the block address in to R14 B(R14);