1061da546Spatrick //===-- EmulateInstructionARM.h ---------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H 11061da546Spatrick 12061da546Spatrick #include "Plugins/Process/Utility/ARMDefines.h" 13061da546Spatrick #include "lldb/Core/EmulateInstruction.h" 14061da546Spatrick #include "lldb/Utility/ConstString.h" 15061da546Spatrick #include "lldb/Utility/Status.h" 16*f6aab3d8Srobert #include <optional> 17061da546Spatrick 18061da546Spatrick namespace lldb_private { 19061da546Spatrick 20061da546Spatrick // ITSession - Keep track of the IT Block progression. 21061da546Spatrick class ITSession { 22061da546Spatrick public: 23be691f3bSpatrick ITSession() = default; 24be691f3bSpatrick ~ITSession() = default; 25061da546Spatrick 26061da546Spatrick // InitIT - Initializes ITCounter/ITState. 27061da546Spatrick bool InitIT(uint32_t bits7_0); 28061da546Spatrick 29061da546Spatrick // ITAdvance - Updates ITCounter/ITState as IT Block progresses. 30061da546Spatrick void ITAdvance(); 31061da546Spatrick 32061da546Spatrick // InITBlock - Returns true if we're inside an IT Block. 33061da546Spatrick bool InITBlock(); 34061da546Spatrick 35061da546Spatrick // LastInITBlock - Returns true if we're the last instruction inside an IT 36061da546Spatrick // Block. 37061da546Spatrick bool LastInITBlock(); 38061da546Spatrick 39061da546Spatrick // GetCond - Gets condition bits for the current thumb instruction. 40061da546Spatrick uint32_t GetCond(); 41061da546Spatrick 42061da546Spatrick private: 43be691f3bSpatrick uint32_t ITCounter = 0; // Possible values: 0, 1, 2, 3, 4. 44be691f3bSpatrick uint32_t ITState = 0; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. 45061da546Spatrick }; 46061da546Spatrick 47061da546Spatrick class EmulateInstructionARM : public EmulateInstruction { 48061da546Spatrick public: 49061da546Spatrick enum ARMEncoding { 50061da546Spatrick eEncodingA1, 51061da546Spatrick eEncodingA2, 52061da546Spatrick eEncodingA3, 53061da546Spatrick eEncodingA4, 54061da546Spatrick eEncodingA5, 55061da546Spatrick eEncodingT1, 56061da546Spatrick eEncodingT2, 57061da546Spatrick eEncodingT3, 58061da546Spatrick eEncodingT4, 59061da546Spatrick eEncodingT5 60061da546Spatrick }; 61061da546Spatrick 62061da546Spatrick static void Initialize(); 63061da546Spatrick 64061da546Spatrick static void Terminate(); 65061da546Spatrick GetPluginNameStatic()66*f6aab3d8Srobert static llvm::StringRef GetPluginNameStatic() { return "arm"; } 67061da546Spatrick 68*f6aab3d8Srobert static llvm::StringRef GetPluginDescriptionStatic(); 69061da546Spatrick 70061da546Spatrick static lldb_private::EmulateInstruction * 71061da546Spatrick CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type); 72061da546Spatrick 73061da546Spatrick static bool SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type)74061da546Spatrick SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type) { 75061da546Spatrick switch (inst_type) { 76061da546Spatrick case eInstructionTypeAny: 77061da546Spatrick case eInstructionTypePrologueEpilogue: 78061da546Spatrick case eInstructionTypePCModifying: 79061da546Spatrick return true; 80061da546Spatrick 81061da546Spatrick case eInstructionTypeAll: 82061da546Spatrick return false; 83061da546Spatrick } 84061da546Spatrick return false; 85061da546Spatrick } 86061da546Spatrick GetPluginName()87*f6aab3d8Srobert llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 88061da546Spatrick 89061da546Spatrick bool SetTargetTriple(const ArchSpec &arch) override; 90061da546Spatrick 91061da546Spatrick enum Mode { eModeInvalid = -1, eModeARM, eModeThumb }; 92061da546Spatrick EmulateInstructionARM(const ArchSpec & arch)93061da546Spatrick EmulateInstructionARM(const ArchSpec &arch) 94061da546Spatrick : EmulateInstruction(arch), m_arm_isa(0), m_opcode_mode(eModeInvalid), 95*f6aab3d8Srobert m_opcode_cpsr(0), m_new_inst_cpsr(0), m_it_session(), 96*f6aab3d8Srobert m_ignore_conditions(false) { 97061da546Spatrick SetArchitecture(arch); 98061da546Spatrick } 99061da546Spatrick 100061da546Spatrick // EmulateInstructionARM (const ArchSpec &arch, 101061da546Spatrick // bool ignore_conditions, 102061da546Spatrick // void *baton, 103061da546Spatrick // ReadMemory read_mem_callback, 104061da546Spatrick // WriteMemory write_mem_callback, 105061da546Spatrick // ReadRegister read_reg_callback, 106061da546Spatrick // WriteRegister write_reg_callback) : 107061da546Spatrick // EmulateInstruction (arch, 108061da546Spatrick // ignore_conditions, 109061da546Spatrick // baton, 110061da546Spatrick // read_mem_callback, 111061da546Spatrick // write_mem_callback, 112061da546Spatrick // read_reg_callback, 113061da546Spatrick // write_reg_callback), 114061da546Spatrick // m_arm_isa (0), 115061da546Spatrick // m_opcode_mode (eModeInvalid), 116061da546Spatrick // m_opcode_cpsr (0), 117061da546Spatrick // m_it_session () 118061da546Spatrick // { 119061da546Spatrick // } 120061da546Spatrick SupportsEmulatingInstructionsOfType(InstructionType inst_type)121061da546Spatrick bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override { 122061da546Spatrick return SupportsEmulatingInstructionsOfTypeStatic(inst_type); 123061da546Spatrick } 124061da546Spatrick 125061da546Spatrick virtual bool SetArchitecture(const ArchSpec &arch); 126061da546Spatrick 127061da546Spatrick bool ReadInstruction() override; 128061da546Spatrick 129061da546Spatrick bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, 130061da546Spatrick Target *target) override; 131061da546Spatrick 132061da546Spatrick bool EvaluateInstruction(uint32_t evaluate_options) override; 133061da546Spatrick 134061da546Spatrick InstructionCondition GetInstructionCondition() override; 135061da546Spatrick 136061da546Spatrick bool TestEmulation(Stream *out_stream, ArchSpec &arch, 137061da546Spatrick OptionValueDictionary *test_data) override; 138061da546Spatrick 139*f6aab3d8Srobert std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind, 140*f6aab3d8Srobert uint32_t reg_num) override; 141061da546Spatrick 142061da546Spatrick bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override; 143061da546Spatrick 144061da546Spatrick uint32_t ArchVersion(); 145061da546Spatrick 146061da546Spatrick bool ConditionPassed(const uint32_t opcode); 147061da546Spatrick 148061da546Spatrick uint32_t CurrentCond(const uint32_t opcode); 149061da546Spatrick 150061da546Spatrick // InITBlock - Returns true if we're in Thumb mode and inside an IT Block. 151061da546Spatrick bool InITBlock(); 152061da546Spatrick 153061da546Spatrick // LastInITBlock - Returns true if we're in Thumb mode and the last 154061da546Spatrick // instruction inside an IT Block. 155061da546Spatrick bool LastInITBlock(); 156061da546Spatrick 157061da546Spatrick bool BadMode(uint32_t mode); 158061da546Spatrick 159061da546Spatrick bool CurrentModeIsPrivileged(); 160061da546Spatrick 161061da546Spatrick void CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 162061da546Spatrick bool affect_execstate); 163061da546Spatrick 164061da546Spatrick bool BranchWritePC(const Context &context, uint32_t addr); 165061da546Spatrick 166061da546Spatrick bool BXWritePC(Context &context, uint32_t addr); 167061da546Spatrick 168061da546Spatrick bool LoadWritePC(Context &context, uint32_t addr); 169061da546Spatrick 170061da546Spatrick bool ALUWritePC(Context &context, uint32_t addr); 171061da546Spatrick 172061da546Spatrick Mode CurrentInstrSet(); 173061da546Spatrick 174061da546Spatrick bool SelectInstrSet(Mode arm_or_thumb); 175061da546Spatrick 176061da546Spatrick bool WriteBits32Unknown(int n); 177061da546Spatrick 178061da546Spatrick bool WriteBits32UnknownToMemory(lldb::addr_t address); 179061da546Spatrick 180061da546Spatrick bool UnalignedSupport(); 181061da546Spatrick 182061da546Spatrick typedef struct { 183061da546Spatrick uint32_t result; 184061da546Spatrick uint8_t carry_out; 185061da546Spatrick uint8_t overflow; 186061da546Spatrick } AddWithCarryResult; 187061da546Spatrick 188061da546Spatrick AddWithCarryResult AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in); 189061da546Spatrick 190061da546Spatrick // Helper method to read the content of an ARM core register. 191061da546Spatrick uint32_t ReadCoreReg(uint32_t regnum, bool *success); 192061da546Spatrick 193061da546Spatrick // See A8.6.96 MOV (immediate) Operation. 194061da546Spatrick // Default arguments are specified for carry and overflow parameters, which 195061da546Spatrick // means 196061da546Spatrick // not to update the respective flags even if setflags is true. 197061da546Spatrick bool WriteCoreRegOptionalFlags(Context &context, const uint32_t result, 198061da546Spatrick const uint32_t Rd, bool setflags, 199061da546Spatrick const uint32_t carry = ~0u, 200061da546Spatrick const uint32_t overflow = ~0u); 201061da546Spatrick WriteCoreReg(Context & context,const uint32_t result,const uint32_t Rd)202061da546Spatrick bool WriteCoreReg(Context &context, const uint32_t result, 203061da546Spatrick const uint32_t Rd) { 204061da546Spatrick // Don't set the flags. 205061da546Spatrick return WriteCoreRegOptionalFlags(context, result, Rd, false); 206061da546Spatrick } 207061da546Spatrick 208061da546Spatrick // See A8.6.35 CMP (immediate) Operation. 209061da546Spatrick // Default arguments are specified for carry and overflow parameters, which 210061da546Spatrick // means 211061da546Spatrick // not to update the respective flags. 212061da546Spatrick bool WriteFlags(Context &context, const uint32_t result, 213061da546Spatrick const uint32_t carry = ~0u, const uint32_t overflow = ~0u); 214061da546Spatrick MemARead(EmulateInstruction::Context & context,lldb::addr_t address,uint32_t size,uint64_t fail_value,bool * success_ptr)215061da546Spatrick inline uint64_t MemARead(EmulateInstruction::Context &context, 216061da546Spatrick lldb::addr_t address, uint32_t size, 217061da546Spatrick uint64_t fail_value, bool *success_ptr) { 218061da546Spatrick // This is a stub function corresponding to "MemA[]" in the ARM manual 219061da546Spatrick // pseudocode, for 220061da546Spatrick // aligned reads from memory. Since we are not trying to write a full 221061da546Spatrick // hardware simulator, and since 222061da546Spatrick // we are running in User mode (rather than Kernel mode) and therefore won't 223061da546Spatrick // have access to many of the 224061da546Spatrick // system registers we would need in order to fully implement this function, 225061da546Spatrick // we will just call 226061da546Spatrick // ReadMemoryUnsigned from here. In the future, if we decide we do need to 227061da546Spatrick // do more faithful emulation of 228061da546Spatrick // the hardware, we can update this function appropriately. 229061da546Spatrick 230061da546Spatrick return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr); 231061da546Spatrick } 232061da546Spatrick MemAWrite(EmulateInstruction::Context & context,lldb::addr_t address,uint64_t data_val,uint32_t size)233061da546Spatrick inline bool MemAWrite(EmulateInstruction::Context &context, 234061da546Spatrick lldb::addr_t address, uint64_t data_val, uint32_t size) 235061da546Spatrick 236061da546Spatrick { 237061da546Spatrick // This is a stub function corresponding to "MemA[]" in the ARM manual 238061da546Spatrick // pseudocode, for 239061da546Spatrick // aligned writes to memory. Since we are not trying to write a full 240061da546Spatrick // hardware simulator, and since 241061da546Spatrick // we are running in User mode (rather than Kernel mode) and therefore won't 242061da546Spatrick // have access to many of the 243061da546Spatrick // system registers we would need in order to fully implement this function, 244061da546Spatrick // we will just call 245061da546Spatrick // WriteMemoryUnsigned from here. In the future, if we decide we do need to 246061da546Spatrick // do more faithful emulation of 247061da546Spatrick // the hardware, we can update this function appropriately. 248061da546Spatrick 249061da546Spatrick return WriteMemoryUnsigned(context, address, data_val, size); 250061da546Spatrick } 251061da546Spatrick MemURead(EmulateInstruction::Context & context,lldb::addr_t address,uint32_t size,uint64_t fail_value,bool * success_ptr)252061da546Spatrick inline uint64_t MemURead(EmulateInstruction::Context &context, 253061da546Spatrick lldb::addr_t address, uint32_t size, 254061da546Spatrick uint64_t fail_value, bool *success_ptr) { 255061da546Spatrick // This is a stub function corresponding to "MemU[]" in the ARM manual 256061da546Spatrick // pseudocode, for 257061da546Spatrick // unaligned reads from memory. Since we are not trying to write a full 258061da546Spatrick // hardware simulator, and since 259061da546Spatrick // we are running in User mode (rather than Kernel mode) and therefore won't 260061da546Spatrick // have access to many of the 261061da546Spatrick // system registers we would need in order to fully implement this function, 262061da546Spatrick // we will just call 263061da546Spatrick // ReadMemoryUnsigned from here. In the future, if we decide we do need to 264061da546Spatrick // do more faithful emulation of 265061da546Spatrick // the hardware, we can update this function appropriately. 266061da546Spatrick 267061da546Spatrick return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr); 268061da546Spatrick } 269061da546Spatrick MemUWrite(EmulateInstruction::Context & context,lldb::addr_t address,uint64_t data_val,uint32_t size)270061da546Spatrick inline bool MemUWrite(EmulateInstruction::Context &context, 271061da546Spatrick lldb::addr_t address, uint64_t data_val, uint32_t size) 272061da546Spatrick 273061da546Spatrick { 274061da546Spatrick // This is a stub function corresponding to "MemU[]" in the ARM manual 275061da546Spatrick // pseudocode, for 276061da546Spatrick // unaligned writes to memory. Since we are not trying to write a full 277061da546Spatrick // hardware simulator, and since 278061da546Spatrick // we are running in User mode (rather than Kernel mode) and therefore won't 279061da546Spatrick // have access to many of the 280061da546Spatrick // system registers we would need in order to fully implement this function, 281061da546Spatrick // we will just call 282061da546Spatrick // WriteMemoryUnsigned from here. In the future, if we decide we do need to 283061da546Spatrick // do more faithful emulation of 284061da546Spatrick // the hardware, we can update this function appropriately. 285061da546Spatrick 286061da546Spatrick return WriteMemoryUnsigned(context, address, data_val, size); 287061da546Spatrick } 288061da546Spatrick 289061da546Spatrick protected: 290061da546Spatrick // Typedef for the callback function used during the emulation. 291061da546Spatrick // Pass along (ARMEncoding)encoding as the callback data. 292061da546Spatrick enum ARMInstrSize { eSize16, eSize32 }; 293061da546Spatrick 294061da546Spatrick typedef struct { 295061da546Spatrick uint32_t mask; 296061da546Spatrick uint32_t value; 297061da546Spatrick uint32_t variants; 298061da546Spatrick EmulateInstructionARM::ARMEncoding encoding; 299061da546Spatrick uint32_t vfp_variants; 300061da546Spatrick ARMInstrSize size; 301061da546Spatrick bool (EmulateInstructionARM::*callback)( 302061da546Spatrick const uint32_t opcode, 303061da546Spatrick const EmulateInstructionARM::ARMEncoding encoding); 304061da546Spatrick const char *name; 305061da546Spatrick } ARMOpcode; 306061da546Spatrick 307061da546Spatrick uint32_t GetFramePointerRegisterNumber() const; 308061da546Spatrick 309061da546Spatrick uint32_t GetFramePointerDWARFRegisterNumber() const; 310061da546Spatrick 311061da546Spatrick static ARMOpcode *GetARMOpcodeForInstruction(const uint32_t opcode, 312061da546Spatrick uint32_t isa_mask); 313061da546Spatrick 314061da546Spatrick static ARMOpcode *GetThumbOpcodeForInstruction(const uint32_t opcode, 315061da546Spatrick uint32_t isa_mask); 316061da546Spatrick 317061da546Spatrick // A8.6.123 PUSH 318061da546Spatrick bool EmulatePUSH(const uint32_t opcode, const ARMEncoding encoding); 319061da546Spatrick 320061da546Spatrick // A8.6.122 POP 321061da546Spatrick bool EmulatePOP(const uint32_t opcode, const ARMEncoding encoding); 322061da546Spatrick 323061da546Spatrick // A8.6.8 ADD (SP plus immediate) 324061da546Spatrick bool EmulateADDRdSPImm(const uint32_t opcode, const ARMEncoding encoding); 325061da546Spatrick 326061da546Spatrick // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp 327061da546Spatrick bool EmulateMOVRdSP(const uint32_t opcode, const ARMEncoding encoding); 328061da546Spatrick 329061da546Spatrick // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7 330061da546Spatrick bool EmulateMOVLowHigh(const uint32_t opcode, const ARMEncoding encoding); 331061da546Spatrick 332061da546Spatrick // A8.6.59 LDR (literal) 333061da546Spatrick bool EmulateLDRRtPCRelative(const uint32_t opcode, 334061da546Spatrick const ARMEncoding encoding); 335061da546Spatrick 336061da546Spatrick // A8.6.8 ADD (SP plus immediate) 337061da546Spatrick bool EmulateADDSPImm(const uint32_t opcode, const ARMEncoding encoding); 338061da546Spatrick 339061da546Spatrick // A8.6.9 ADD (SP plus register) 340061da546Spatrick bool EmulateADDSPRm(const uint32_t opcode, const ARMEncoding encoding); 341061da546Spatrick 342061da546Spatrick // A8.6.23 BL, BLX (immediate) 343061da546Spatrick bool EmulateBLXImmediate(const uint32_t opcode, const ARMEncoding encoding); 344061da546Spatrick 345061da546Spatrick // A8.6.24 BLX (register) 346061da546Spatrick bool EmulateBLXRm(const uint32_t opcode, const ARMEncoding encoding); 347061da546Spatrick 348061da546Spatrick // A8.6.25 BX 349061da546Spatrick bool EmulateBXRm(const uint32_t opcode, const ARMEncoding encoding); 350061da546Spatrick 351061da546Spatrick // A8.6.26 BXJ 352061da546Spatrick bool EmulateBXJRm(const uint32_t opcode, const ARMEncoding encoding); 353061da546Spatrick 354061da546Spatrick // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip 355061da546Spatrick bool EmulateSUBR7IPImm(const uint32_t opcode, const ARMEncoding encoding); 356061da546Spatrick 357061da546Spatrick // A8.6.215 SUB (SP minus immediate) -- Rd == ip 358061da546Spatrick bool EmulateSUBIPSPImm(const uint32_t opcode, const ARMEncoding encoding); 359061da546Spatrick 360061da546Spatrick // A8.6.215 SUB (SP minus immediate) 361061da546Spatrick bool EmulateSUBSPImm(const uint32_t opcode, const ARMEncoding encoding); 362061da546Spatrick 363061da546Spatrick // A8.6.216 SUB (SP minus register) 364061da546Spatrick bool EmulateSUBSPReg(const uint32_t opcode, const ARMEncoding encoding); 365061da546Spatrick 366061da546Spatrick // A8.6.194 STR (immediate, ARM) -- Rn == sp 367061da546Spatrick bool EmulateSTRRtSP(const uint32_t opcode, const ARMEncoding encoding); 368061da546Spatrick 369061da546Spatrick // A8.6.355 VPUSH 370061da546Spatrick bool EmulateVPUSH(const uint32_t opcode, const ARMEncoding encoding); 371061da546Spatrick 372061da546Spatrick // A8.6.354 VPOP 373061da546Spatrick bool EmulateVPOP(const uint32_t opcode, const ARMEncoding encoding); 374061da546Spatrick 375061da546Spatrick // A8.6.218 SVC (previously SWI) 376061da546Spatrick bool EmulateSVC(const uint32_t opcode, const ARMEncoding encoding); 377061da546Spatrick 378061da546Spatrick // A8.6.50 IT 379061da546Spatrick bool EmulateIT(const uint32_t opcode, const ARMEncoding encoding); 380061da546Spatrick 381061da546Spatrick // NOP 382061da546Spatrick bool EmulateNop(const uint32_t opcode, const ARMEncoding encoding); 383061da546Spatrick 384061da546Spatrick // A8.6.16 B 385061da546Spatrick bool EmulateB(const uint32_t opcode, const ARMEncoding encoding); 386061da546Spatrick 387061da546Spatrick // A8.6.27 CBNZ, CBZ 388061da546Spatrick bool EmulateCB(const uint32_t opcode, const ARMEncoding encoding); 389061da546Spatrick 390061da546Spatrick // A8.6.226 TBB, TBH 391061da546Spatrick bool EmulateTB(const uint32_t opcode, const ARMEncoding encoding); 392061da546Spatrick 393061da546Spatrick // A8.6.4 ADD (immediate, Thumb) 394061da546Spatrick bool EmulateADDImmThumb(const uint32_t opcode, const ARMEncoding encoding); 395061da546Spatrick 396061da546Spatrick // A8.6.5 ADD (immediate, ARM) 397061da546Spatrick bool EmulateADDImmARM(const uint32_t opcode, const ARMEncoding encoding); 398061da546Spatrick 399061da546Spatrick // A8.6.6 ADD (register) 400061da546Spatrick bool EmulateADDReg(const uint32_t opcode, const ARMEncoding encoding); 401061da546Spatrick 402061da546Spatrick // A8.6.7 ADD (register-shifted register) 403061da546Spatrick bool EmulateADDRegShift(const uint32_t opcode, const ARMEncoding encoding); 404061da546Spatrick 405061da546Spatrick // A8.6.97 MOV (register) 406061da546Spatrick bool EmulateMOVRdRm(const uint32_t opcode, const ARMEncoding encoding); 407061da546Spatrick 408061da546Spatrick // A8.6.96 MOV (immediate) 409061da546Spatrick bool EmulateMOVRdImm(const uint32_t opcode, const ARMEncoding encoding); 410061da546Spatrick 411061da546Spatrick // A8.6.35 CMP (immediate) 412061da546Spatrick bool EmulateCMPImm(const uint32_t opcode, const ARMEncoding encoding); 413061da546Spatrick 414061da546Spatrick // A8.6.36 CMP (register) 415061da546Spatrick bool EmulateCMPReg(const uint32_t opcode, const ARMEncoding encoding); 416061da546Spatrick 417061da546Spatrick // A8.6.14 ASR (immediate) 418061da546Spatrick bool EmulateASRImm(const uint32_t opcode, const ARMEncoding encoding); 419061da546Spatrick 420061da546Spatrick // A8.6.15 ASR (register) 421061da546Spatrick bool EmulateASRReg(const uint32_t opcode, const ARMEncoding encoding); 422061da546Spatrick 423061da546Spatrick // A8.6.88 LSL (immediate) 424061da546Spatrick bool EmulateLSLImm(const uint32_t opcode, const ARMEncoding encoding); 425061da546Spatrick 426061da546Spatrick // A8.6.89 LSL (register) 427061da546Spatrick bool EmulateLSLReg(const uint32_t opcode, const ARMEncoding encoding); 428061da546Spatrick 429061da546Spatrick // A8.6.90 LSR (immediate) 430061da546Spatrick bool EmulateLSRImm(const uint32_t opcode, const ARMEncoding encoding); 431061da546Spatrick 432061da546Spatrick // A8.6.91 LSR (register) 433061da546Spatrick bool EmulateLSRReg(const uint32_t opcode, const ARMEncoding encoding); 434061da546Spatrick 435061da546Spatrick // A8.6.139 ROR (immediate) 436061da546Spatrick bool EmulateRORImm(const uint32_t opcode, const ARMEncoding encoding); 437061da546Spatrick 438061da546Spatrick // A8.6.140 ROR (register) 439061da546Spatrick bool EmulateRORReg(const uint32_t opcode, const ARMEncoding encoding); 440061da546Spatrick 441061da546Spatrick // A8.6.141 RRX 442061da546Spatrick bool EmulateRRX(const uint32_t opcode, const ARMEncoding encoding); 443061da546Spatrick 444061da546Spatrick // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX 445061da546Spatrick bool EmulateShiftImm(const uint32_t opcode, const ARMEncoding encoding, 446061da546Spatrick ARM_ShifterType shift_type); 447061da546Spatrick 448061da546Spatrick // Helper method for ASR, LSL, LSR, and ROR (register) 449061da546Spatrick bool EmulateShiftReg(const uint32_t opcode, const ARMEncoding encoding, 450061da546Spatrick ARM_ShifterType shift_type); 451061da546Spatrick 452061da546Spatrick // LOAD FUNCTIONS 453061da546Spatrick 454061da546Spatrick // A8.6.53 LDM/LDMIA/LDMFD 455061da546Spatrick bool EmulateLDM(const uint32_t opcode, const ARMEncoding encoding); 456061da546Spatrick 457061da546Spatrick // A8.6.54 LDMDA/LDMFA 458061da546Spatrick bool EmulateLDMDA(const uint32_t opcode, const ARMEncoding encoding); 459061da546Spatrick 460061da546Spatrick // A8.6.55 LDMDB/LDMEA 461061da546Spatrick bool EmulateLDMDB(const uint32_t opcode, const ARMEncoding encoding); 462061da546Spatrick 463061da546Spatrick // A8.6.56 LDMIB/LDMED 464061da546Spatrick bool EmulateLDMIB(const uint32_t opcode, const ARMEncoding encoding); 465061da546Spatrick 466061da546Spatrick // A8.6.57 LDR (immediate, Thumb) -- Encoding T1 467061da546Spatrick bool EmulateLDRRtRnImm(const uint32_t opcode, const ARMEncoding encoding); 468061da546Spatrick 469061da546Spatrick // A8.6.58 LDR (immediate, ARM) - Encoding A1 470061da546Spatrick bool EmulateLDRImmediateARM(const uint32_t opcode, 471061da546Spatrick const ARMEncoding encoding); 472061da546Spatrick 473061da546Spatrick // A8.6.59 LDR (literal) 474061da546Spatrick bool EmulateLDRLiteral(const uint32_t, const ARMEncoding encoding); 475061da546Spatrick 476061da546Spatrick // A8.6.60 LDR (register) - Encoding T1, T2, A1 477061da546Spatrick bool EmulateLDRRegister(const uint32_t opcode, const ARMEncoding encoding); 478061da546Spatrick 479061da546Spatrick // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3 480061da546Spatrick bool EmulateLDRBImmediate(const uint32_t opcode, const ARMEncoding encoding); 481061da546Spatrick 482061da546Spatrick // A8.6.62 LDRB (immediate, ARM) 483061da546Spatrick bool EmulateLDRBImmediateARM(const uint32_t opcode, 484061da546Spatrick const ARMEncoding encoding); 485061da546Spatrick 486061da546Spatrick // A8.6.63 LDRB (literal) - Encoding T1, A1 487061da546Spatrick bool EmulateLDRBLiteral(const uint32_t opcode, const ARMEncoding encoding); 488061da546Spatrick 489061da546Spatrick // A8.6.64 LDRB (register) - Encoding T1, T2, A1 490061da546Spatrick bool EmulateLDRBRegister(const uint32_t opcode, const ARMEncoding encoding); 491061da546Spatrick 492061da546Spatrick // A8.6.65 LDRBT 493061da546Spatrick bool EmulateLDRBT(const uint32_t opcode, const ARMEncoding encoding); 494061da546Spatrick 495061da546Spatrick // A8.6.66 LDRD (immediate) 496061da546Spatrick bool EmulateLDRDImmediate(const uint32_t opcode, const ARMEncoding encoding); 497061da546Spatrick 498061da546Spatrick // A8.6.67 499061da546Spatrick bool EmulateLDRDLiteral(const uint32_t opcode, const ARMEncoding encoding); 500061da546Spatrick 501061da546Spatrick // A8.6.68 LDRD (register) 502061da546Spatrick bool EmulateLDRDRegister(const uint32_t opcode, const ARMEncoding encoding); 503061da546Spatrick 504061da546Spatrick // A8.6.69 LDREX 505061da546Spatrick bool EmulateLDREX(const uint32_t opcode, const ARMEncoding encoding); 506061da546Spatrick 507061da546Spatrick // A8.6.70 LDREXB 508061da546Spatrick bool EmulateLDREXB(const uint32_t opcode, const ARMEncoding encoding); 509061da546Spatrick 510061da546Spatrick // A8.6.71 LDREXD 511061da546Spatrick bool EmulateLDREXD(const uint32_t opcode, const ARMEncoding encoding); 512061da546Spatrick 513061da546Spatrick // A8.6.72 LDREXH 514061da546Spatrick bool EmulateLDREXH(const uint32_t opcode, const ARMEncoding encoding); 515061da546Spatrick 516061da546Spatrick // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3 517061da546Spatrick bool EmulateLDRHImmediate(const uint32_t opcode, const ARMEncoding encoding); 518061da546Spatrick 519061da546Spatrick // A8.6.74 LDRS (immediate, ARM) 520061da546Spatrick bool EmulateLDRHImmediateARM(const uint32_t opcode, 521061da546Spatrick const ARMEncoding encoding); 522061da546Spatrick 523061da546Spatrick // A8.6.75 LDRH (literal) - Encoding T1, A1 524061da546Spatrick bool EmulateLDRHLiteral(const uint32_t opcode, const ARMEncoding encoding); 525061da546Spatrick 526061da546Spatrick // A8.6.76 LDRH (register) - Encoding T1, T2, A1 527061da546Spatrick bool EmulateLDRHRegister(const uint32_t opcode, const ARMEncoding encoding); 528061da546Spatrick 529061da546Spatrick // A8.6.77 LDRHT 530061da546Spatrick bool EmulateLDRHT(const uint32_t opcode, const ARMEncoding encoding); 531061da546Spatrick 532061da546Spatrick // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1 533061da546Spatrick bool EmulateLDRSBImmediate(const uint32_t opcode, const ARMEncoding encoding); 534061da546Spatrick 535061da546Spatrick // A8.6.79 LDRSB (literal) - Encoding T1, A1 536061da546Spatrick bool EmulateLDRSBLiteral(const uint32_t opcode, const ARMEncoding encoding); 537061da546Spatrick 538061da546Spatrick // A8.6.80 LDRSB (register) - Encoding T1, T2, A1 539061da546Spatrick bool EmulateLDRSBRegister(const uint32_t opcode, const ARMEncoding encoding); 540061da546Spatrick 541061da546Spatrick // A8.6.81 LDRSBT 542061da546Spatrick bool EmulateLDRSBT(const uint32_t opcode, const ARMEncoding encoding); 543061da546Spatrick 544061da546Spatrick // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1 545061da546Spatrick bool EmulateLDRSHImmediate(const uint32_t opcode, const ARMEncoding encoding); 546061da546Spatrick 547061da546Spatrick // A8.6.83 LDRSH (literal) - Encoding T1, A1 548061da546Spatrick bool EmulateLDRSHLiteral(const uint32_t opcode, const ARMEncoding encoding); 549061da546Spatrick 550061da546Spatrick // A8.6.84 LDRSH (register) - Encoding T1, T2, A1 551061da546Spatrick bool EmulateLDRSHRegister(const uint32_t opcode, const ARMEncoding encoding); 552061da546Spatrick 553061da546Spatrick // A8.6.85 LDRSHT 554061da546Spatrick bool EmulateLDRSHT(const uint32_t opcode, const ARMEncoding encoding); 555061da546Spatrick 556061da546Spatrick // A8.6.86 557061da546Spatrick bool EmulateLDRT(const uint32_t opcode, const ARMEncoding encoding); 558061da546Spatrick 559061da546Spatrick // STORE FUNCTIONS 560061da546Spatrick 561061da546Spatrick // A8.6.189 STM/STMIA/STMEA 562061da546Spatrick bool EmulateSTM(const uint32_t opcode, const ARMEncoding encoding); 563061da546Spatrick 564061da546Spatrick // A8.6.190 STMDA/STMED 565061da546Spatrick bool EmulateSTMDA(const uint32_t opcode, const ARMEncoding encoding); 566061da546Spatrick 567061da546Spatrick // A8.6.191 STMDB/STMFD 568061da546Spatrick bool EmulateSTMDB(const uint32_t opcode, const ARMEncoding encoding); 569061da546Spatrick 570061da546Spatrick // A8.6.192 STMIB/STMFA 571061da546Spatrick bool EmulateSTMIB(const uint32_t opcode, const ARMEncoding encoding); 572061da546Spatrick 573061da546Spatrick // A8.6.193 STR (immediate, Thumb) 574061da546Spatrick bool EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding); 575061da546Spatrick 576061da546Spatrick // A8.6.194 STR (immediate, ARM) 577061da546Spatrick bool EmulateSTRImmARM(const uint32_t opcode, const ARMEncoding encoding); 578061da546Spatrick 579061da546Spatrick // A8.6.195 STR (register) 580061da546Spatrick bool EmulateSTRRegister(const uint32_t opcode, const ARMEncoding encoding); 581061da546Spatrick 582061da546Spatrick // A8.6.196 STRB (immediate, Thumb) 583061da546Spatrick bool EmulateSTRBThumb(const uint32_t opcode, const ARMEncoding encoding); 584061da546Spatrick 585061da546Spatrick // A8.6.197 STRB (immediate, ARM) 586061da546Spatrick bool EmulateSTRBImmARM(const uint32_t opcode, const ARMEncoding encoding); 587061da546Spatrick 588061da546Spatrick // A8.6.198 STRB (register) 589061da546Spatrick bool EmulateSTRBReg(const uint32_t opcode, const ARMEncoding encoding); 590061da546Spatrick 591061da546Spatrick // A8.6.199 STRBT 592061da546Spatrick bool EmulateSTRBT(const uint32_t opcode, const ARMEncoding encoding); 593061da546Spatrick 594061da546Spatrick // A8.6.200 STRD (immediate) 595061da546Spatrick bool EmulateSTRDImm(const uint32_t opcode, const ARMEncoding encoding); 596061da546Spatrick 597061da546Spatrick // A8.6.201 STRD (register) 598061da546Spatrick bool EmulateSTRDReg(const uint32_t opcode, const ARMEncoding encoding); 599061da546Spatrick 600061da546Spatrick // A8.6.202 STREX 601061da546Spatrick bool EmulateSTREX(const uint32_t opcode, const ARMEncoding encoding); 602061da546Spatrick 603061da546Spatrick // A8.6.203 STREXB 604061da546Spatrick bool EmulateSTREXB(const uint32_t opcode, const ARMEncoding encoding); 605061da546Spatrick 606061da546Spatrick // A8.6.204 STREXD 607061da546Spatrick bool EmulateSTREXD(const uint32_t opcode, const ARMEncoding encoding); 608061da546Spatrick 609061da546Spatrick // A8.6.205 STREXH 610061da546Spatrick bool EmulateSTREXH(const uint32_t opcode, const ARMEncoding encoding); 611061da546Spatrick 612061da546Spatrick // A8.6.206 STRH (immediate, Thumb) 613061da546Spatrick bool EmulateSTRHImmThumb(const uint32_t opcode, const ARMEncoding encoding); 614061da546Spatrick 615061da546Spatrick // A8.6.207 STRH (immediate, ARM) 616061da546Spatrick bool EmulateSTRHImmARM(const uint32_t opcode, const ARMEncoding encoding); 617061da546Spatrick 618061da546Spatrick // A8.6.208 STRH (register) 619061da546Spatrick bool EmulateSTRHRegister(const uint32_t opcode, const ARMEncoding encoding); 620061da546Spatrick 621061da546Spatrick // A8.6.209 STRHT 622061da546Spatrick bool EmulateSTRHT(const uint32_t opcode, const ARMEncoding encoding); 623061da546Spatrick 624061da546Spatrick // A8.6.210 STRT 625061da546Spatrick bool EmulateSTRT(const uint32_t opcode, const ARMEncoding encoding); 626061da546Spatrick 627061da546Spatrick // A8.6.1 ADC (immediate) 628061da546Spatrick bool EmulateADCImm(const uint32_t opcode, const ARMEncoding encoding); 629061da546Spatrick 630061da546Spatrick // A8.6.2 ADC (Register) 631061da546Spatrick bool EmulateADCReg(const uint32_t opcode, const ARMEncoding encoding); 632061da546Spatrick 633061da546Spatrick // A8.6.10 ADR 634061da546Spatrick bool EmulateADR(const uint32_t opcode, const ARMEncoding encoding); 635061da546Spatrick 636061da546Spatrick // A8.6.11 AND (immediate) 637061da546Spatrick bool EmulateANDImm(const uint32_t opcode, const ARMEncoding encoding); 638061da546Spatrick 639061da546Spatrick // A8.6.12 AND (register) 640061da546Spatrick bool EmulateANDReg(const uint32_t opcode, const ARMEncoding encoding); 641061da546Spatrick 642061da546Spatrick // A8.6.19 BIC (immediate) 643061da546Spatrick bool EmulateBICImm(const uint32_t opcode, const ARMEncoding encoding); 644061da546Spatrick 645061da546Spatrick // A8.6.20 BIC (register) 646061da546Spatrick bool EmulateBICReg(const uint32_t opcode, const ARMEncoding encoding); 647061da546Spatrick 648061da546Spatrick // A8.6.26 BXJ 649061da546Spatrick bool EmulateBXJ(const uint32_t opcode, const ARMEncoding encoding); 650061da546Spatrick 651061da546Spatrick // A8.6.32 CMN (immediate) 652061da546Spatrick bool EmulateCMNImm(const uint32_t opcode, const ARMEncoding encoding); 653061da546Spatrick 654061da546Spatrick // A8.6.33 CMN (register) 655061da546Spatrick bool EmulateCMNReg(const uint32_t opcode, const ARMEncoding encoding); 656061da546Spatrick 657061da546Spatrick // A8.6.44 EOR (immediate) 658061da546Spatrick bool EmulateEORImm(const uint32_t opcode, const ARMEncoding encoding); 659061da546Spatrick 660061da546Spatrick // A8.6.45 EOR (register) 661061da546Spatrick bool EmulateEORReg(const uint32_t opcode, const ARMEncoding encoding); 662061da546Spatrick 663061da546Spatrick // A8.6.105 MUL 664061da546Spatrick bool EmulateMUL(const uint32_t opcode, const ARMEncoding encoding); 665061da546Spatrick 666061da546Spatrick // A8.6.106 MVN (immediate) 667061da546Spatrick bool EmulateMVNImm(const uint32_t opcode, const ARMEncoding encoding); 668061da546Spatrick 669061da546Spatrick // A8.6.107 MVN (register) 670061da546Spatrick bool EmulateMVNReg(const uint32_t opcode, const ARMEncoding encoding); 671061da546Spatrick 672061da546Spatrick // A8.6.113 ORR (immediate) 673061da546Spatrick bool EmulateORRImm(const uint32_t opcode, const ARMEncoding encoding); 674061da546Spatrick 675061da546Spatrick // A8.6.114 ORR (register) 676061da546Spatrick bool EmulateORRReg(const uint32_t opcode, const ARMEncoding encoding); 677061da546Spatrick 678061da546Spatrick // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1 679061da546Spatrick bool EmulatePLDImmediate(const uint32_t opcode, const ARMEncoding encoding); 680061da546Spatrick 681061da546Spatrick // A8.6.119 PLI (immediate,literal) - Encoding T3, A1 682061da546Spatrick bool EmulatePLIImmediate(const uint32_t opcode, const ARMEncoding encoding); 683061da546Spatrick 684061da546Spatrick // A8.6.120 PLI (register) - Encoding T1, A1 685061da546Spatrick bool EmulatePLIRegister(const uint32_t opcode, const ARMEncoding encoding); 686061da546Spatrick 687061da546Spatrick // A8.6.141 RSB (immediate) 688061da546Spatrick bool EmulateRSBImm(const uint32_t opcode, const ARMEncoding encoding); 689061da546Spatrick 690061da546Spatrick // A8.6.142 RSB (register) 691061da546Spatrick bool EmulateRSBReg(const uint32_t opcode, const ARMEncoding encoding); 692061da546Spatrick 693061da546Spatrick // A8.6.144 RSC (immediate) 694061da546Spatrick bool EmulateRSCImm(const uint32_t opcode, const ARMEncoding encoding); 695061da546Spatrick 696061da546Spatrick // A8.6.145 RSC (register) 697061da546Spatrick bool EmulateRSCReg(const uint32_t opcode, const ARMEncoding encoding); 698061da546Spatrick 699061da546Spatrick // A8.6.150 SBC (immediate) 700061da546Spatrick bool EmulateSBCImm(const uint32_t opcode, const ARMEncoding encoding); 701061da546Spatrick 702061da546Spatrick // A8.6.151 SBC (register) 703061da546Spatrick bool EmulateSBCReg(const uint32_t opcode, const ARMEncoding encoding); 704061da546Spatrick 705061da546Spatrick // A8.6.211 SUB (immediate, Thumb) 706061da546Spatrick bool EmulateSUBImmThumb(const uint32_t opcode, const ARMEncoding encoding); 707061da546Spatrick 708061da546Spatrick // A8.6.212 SUB (immediate, ARM) 709061da546Spatrick bool EmulateSUBImmARM(const uint32_t opcode, const ARMEncoding encoding); 710061da546Spatrick 711061da546Spatrick // A8.6.213 SUB (register) 712061da546Spatrick bool EmulateSUBReg(const uint32_t opcode, const ARMEncoding encoding); 713061da546Spatrick 714061da546Spatrick // A8.6.214 SUB (register-shifted register) 715061da546Spatrick bool EmulateSUBRegShift(const uint32_t opcode, const ARMEncoding encoding); 716061da546Spatrick 717061da546Spatrick // A8.6.222 SXTB - Encoding T1 718061da546Spatrick bool EmulateSXTB(const uint32_t opcode, const ARMEncoding encoding); 719061da546Spatrick 720061da546Spatrick // A8.6.224 SXTH - EncodingT1 721061da546Spatrick bool EmulateSXTH(const uint32_t opcode, const ARMEncoding encoding); 722061da546Spatrick 723061da546Spatrick // A8.6.227 TEQ (immediate) - Encoding A1 724061da546Spatrick bool EmulateTEQImm(const uint32_t opcode, const ARMEncoding encoding); 725061da546Spatrick 726061da546Spatrick // A8.6.228 TEQ (register) - Encoding A1 727061da546Spatrick bool EmulateTEQReg(const uint32_t opcode, const ARMEncoding encoding); 728061da546Spatrick 729061da546Spatrick // A8.6.230 TST (immediate) - Encoding A1 730061da546Spatrick bool EmulateTSTImm(const uint32_t opcode, const ARMEncoding encoding); 731061da546Spatrick 732061da546Spatrick // A8.6.231 TST (register) - Encoding T1, A1 733061da546Spatrick bool EmulateTSTReg(const uint32_t opcode, const ARMEncoding encoding); 734061da546Spatrick 735061da546Spatrick // A8.6.262 UXTB - Encoding T1 736061da546Spatrick bool EmulateUXTB(const uint32_t opcode, const ARMEncoding encoding); 737061da546Spatrick 738061da546Spatrick // A8.6.264 UXTH - Encoding T1 739061da546Spatrick bool EmulateUXTH(const uint32_t opcode, const ARMEncoding encoding); 740061da546Spatrick 741061da546Spatrick // B6.1.8 RFE 742061da546Spatrick bool EmulateRFE(const uint32_t opcode, const ARMEncoding encoding); 743061da546Spatrick 744061da546Spatrick // A8.6.319 VLDM 745061da546Spatrick bool EmulateVLDM(const uint32_t opcode, const ARMEncoding encoding); 746061da546Spatrick 747061da546Spatrick // A8.6.399 VSTM 748061da546Spatrick bool EmulateVSTM(const uint32_t opcode, const ARMEncoding encoding); 749061da546Spatrick 750061da546Spatrick // A8.6.307 VLD1 (multiple single elements) 751061da546Spatrick bool EmulateVLD1Multiple(const uint32_t opcode, const ARMEncoding encoding); 752061da546Spatrick 753061da546Spatrick // A8.6.308 VLD1 (single element to one lane) 754061da546Spatrick bool EmulateVLD1Single(const uint32_t opcode, const ARMEncoding encoding); 755061da546Spatrick 756061da546Spatrick // A8.6.309 VLD1 (single element to all lanes) 757061da546Spatrick bool EmulateVLD1SingleAll(const uint32_t opcode, const ARMEncoding encoding); 758061da546Spatrick 759061da546Spatrick // A8.6.391 VST1 (multiple single elements) 760061da546Spatrick bool EmulateVST1Multiple(const uint32_t opcode, const ARMEncoding encoding); 761061da546Spatrick 762061da546Spatrick // A8.6.392 VST1 (single element from one lane) 763061da546Spatrick bool EmulateVST1Single(const uint32_t opcode, const ARMEncoding encoding); 764061da546Spatrick 765061da546Spatrick // A8.6.317 VLDR 766061da546Spatrick bool EmulateVLDR(const uint32_t opcode, const ARMEncoding encoding); 767061da546Spatrick 768061da546Spatrick // A8.6.400 VSTR 769061da546Spatrick bool EmulateVSTR(const uint32_t opcode, const ARMEncoding encoding); 770061da546Spatrick 771061da546Spatrick // B6.2.13 SUBS PC, LR and related instructions 772061da546Spatrick bool EmulateSUBSPcLrEtc(const uint32_t opcode, const ARMEncoding encoding); 773061da546Spatrick 774061da546Spatrick uint32_t m_arm_isa; 775061da546Spatrick Mode m_opcode_mode; 776061da546Spatrick uint32_t m_opcode_cpsr; 777061da546Spatrick uint32_t m_new_inst_cpsr; // This can get updated by the opcode. 778061da546Spatrick ITSession m_it_session; 779061da546Spatrick bool m_ignore_conditions; 780061da546Spatrick }; 781061da546Spatrick 782061da546Spatrick } // namespace lldb_private 783061da546Spatrick 784dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H 785