From 88544c5f2ce6f306fa0ccb5ce4e4dd976c0026e7 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Mon, 11 Apr 2011 15:51:10 +0000 Subject: Implement ARM emulation function to handle "SUBS PC, LR and related instructions". llvm-svn: 129279 --- .../Instruction/ARM/EmulateInstructionARM.cpp | 286 +++++++++++++++++---- .../Instruction/ARM/EmulateInstructionARM.h | 3 + 2 files changed, 246 insertions(+), 43 deletions(-) (limited to 'lldb/source/Plugins') diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 1cd8440c191..02c477be6d0 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -686,10 +686,10 @@ EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding Rd = Bits32(opcode, 15, 12); Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -777,11 +777,14 @@ EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding break; case eEncodingA1: - // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); Rd = Bits32 (opcode, 15, 12); setflags = BitIsSet (opcode, 20); imm32 = ARMExpandImm_C (opcode, APSR_C, carry); + + // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; + if ((Rd == 15) && setflags) + return EmulateSUBSPcLrEtc (opcode, encoding); break; @@ -986,10 +989,10 @@ EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding e Rd = Bits32(opcode, 15, 12); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm_C(opcode, APSR_C, carry); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -1749,10 +1752,10 @@ EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding Rd = Bits32(opcode, 15, 12); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -5130,9 +5133,9 @@ EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) - // TODO: Emulate SUBS PC, LR and related instructions. + if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -5210,9 +5213,9 @@ EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); - // TODO: Emulate SUBS PC, LR and related instructions. + if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -5352,9 +5355,9 @@ EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - // TODO: Emulate SUBS PC, LR and related instructions. + if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -5436,9 +5439,9 @@ EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); - // TODO: Emulate SUBS PC, LR and related instructions. + if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -5512,10 +5515,10 @@ EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -5594,10 +5597,10 @@ EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8125,10 +8128,10 @@ EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8210,10 +8213,10 @@ EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8290,9 +8293,9 @@ EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) - // TODO: Emulate SUBS PC, LR and related instructions. + if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8374,9 +8377,9 @@ EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); - // TODO: Emulate SUBS PC, LR and related instructions. + if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8452,10 +8455,10 @@ EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8524,10 +8527,10 @@ EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8588,10 +8591,10 @@ EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8651,10 +8654,10 @@ EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8723,10 +8726,10 @@ EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding e Rn = Bits32(opcode, 19, 16); setflags = BitIsSet(opcode, 20); imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8802,10 +8805,10 @@ EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding e Rm = Bits32(opcode, 3, 0); setflags = BitIsSet(opcode, 20); shift_n = DecodeImmShiftARM(opcode, shift_t); + // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -8966,9 +8969,8 @@ EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncodin return EmulateSUBSPImm (opcode, eEncodingA1); // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - // TODO: Emulate SUBS PC, LR and related instructions. if (Rd == 15 && setflags) - return false; + return EmulateSUBSPcLrEtc (opcode, encoding); break; default: return false; @@ -9292,11 +9294,14 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding break; case eEncodingA1: - // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); d = Bits32 (opcode, 15, 12); m = Bits32 (opcode, 3, 0); setflags = BitIsSet (opcode, 20); + + // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; + if (d == 15 && setflags) + EmulateSUBSPcLrEtc (opcode, encoding); // (shift_t, shift_n) = DecodeImmShift(type, imm5); shift_n = DecodeImmShiftARM (opcode, shift_t); @@ -9496,13 +9501,16 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e break; case eEncodingA1: - // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; // if Rn == ‘1101’ then SEE SUB (SP minus register); // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’); d = Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); m = Bits32 (opcode, 3, 0); setflags = BitIsSet (opcode, 20); + + // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; + if ((d == 15) && setflags) + EmulateSUBSPcLrEtc (opcode, encoding); // (shift_t, shift_n) = DecodeImmShift(type, imm5); shift_n = DecodeImmShiftARM (opcode, shift_t); @@ -11864,6 +11872,195 @@ EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEnc return true; } +// B6.2.13 SUBS PC, LR and related instructions +//The SUBS PC, LR, # , , "}, // mul { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s} ,," }, + { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "S PC,# | ,#" }, + { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "S PC,,}" }, //---------------------------------------------------------------------- // Load instructions @@ -12305,6 +12504,7 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls ,," }, // mul { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul ,," }, + { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS PC, LR, #" }, //---------------------------------------------------------------------- diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index c1dd193fdd3..d4d967086f7 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -935,6 +935,9 @@ protected: bool EmulateVSTR (const uint32_t opcode, const ARMEncoding encoding); + // B6.2.13 SUBS PC, LR and related instructions + bool + EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding); uint32_t m_arm_isa; Mode m_opcode_mode; -- cgit v1.2.3