1201360Srdivacky//===-- EmulateInstructionARM.h ---------------------------------*- C++ -*-===// 2201360Srdivacky// 3201360Srdivacky// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4201360Srdivacky// See https://llvm.org/LICENSE.txt for license information. 5201360Srdivacky// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6201360Srdivacky// 7201360Srdivacky//===----------------------------------------------------------------------===// 8201360Srdivacky 9201360Srdivacky#ifndef lldb_EmulateInstructionARM_h_ 10201360Srdivacky#define lldb_EmulateInstructionARM_h_ 11201360Srdivacky 12201360Srdivacky#include "Plugins/Process/Utility/ARMDefines.h" 13201360Srdivacky#include "lldb/Core/EmulateInstruction.h" 14201360Srdivacky#include "lldb/Utility/ConstString.h" 15201360Srdivacky#include "lldb/Utility/Status.h" 16201360Srdivacky 17201360Srdivackynamespace lldb_private { 18201360Srdivacky 19201360Srdivacky// ITSession - Keep track of the IT Block progression. 20201360Srdivackyclass ITSession { 21201360Srdivackypublic: 22201360Srdivacky ITSession() : ITCounter(0), ITState(0) {} 23201360Srdivacky ~ITSession() {} 24201360Srdivacky 25201360Srdivacky // InitIT - Initializes ITCounter/ITState. 26201360Srdivacky bool InitIT(uint32_t bits7_0); 27201360Srdivacky 28201360Srdivacky // ITAdvance - Updates ITCounter/ITState as IT Block progresses. 29201360Srdivacky void ITAdvance(); 30201360Srdivacky 31201360Srdivacky // InITBlock - Returns true if we're inside an IT Block. 32201360Srdivacky bool InITBlock(); 33201360Srdivacky 34201360Srdivacky // LastInITBlock - Returns true if we're the last instruction inside an IT 35201360Srdivacky // Block. 36201360Srdivacky bool LastInITBlock(); 37201360Srdivacky 38201360Srdivacky // GetCond - Gets condition bits for the current thumb instruction. 39201360Srdivacky uint32_t GetCond(); 40201360Srdivacky 41201360Srdivackyprivate: 42201360Srdivacky uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4. 43201360Srdivacky uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. 44201360Srdivacky}; 45201360Srdivacky 46201360Srdivackyclass EmulateInstructionARM : public EmulateInstruction { 47201360Srdivackypublic: 48201360Srdivacky enum ARMEncoding { 49201360Srdivacky eEncodingA1, 50201360Srdivacky eEncodingA2, 51201360Srdivacky eEncodingA3, 52201360Srdivacky eEncodingA4, 53201360Srdivacky eEncodingA5, 54201360Srdivacky eEncodingT1, 55201360Srdivacky eEncodingT2, 56201360Srdivacky eEncodingT3, 57201360Srdivacky eEncodingT4, 58201360Srdivacky eEncodingT5 59201360Srdivacky }; 60201360Srdivacky 61201360Srdivacky static void Initialize(); 62201360Srdivacky 63201360Srdivacky static void Terminate(); 64201360Srdivacky 65201360Srdivacky static lldb_private::ConstString GetPluginNameStatic(); 66201360Srdivacky 67201360Srdivacky static const char *GetPluginDescriptionStatic(); 68201360Srdivacky 69201360Srdivacky static lldb_private::EmulateInstruction * 70201360Srdivacky CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type); 71201360Srdivacky 72201360Srdivacky static bool 73201360Srdivacky SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type) { 74201360Srdivacky switch (inst_type) { 75201360Srdivacky case eInstructionTypeAny: 76201360Srdivacky case eInstructionTypePrologueEpilogue: 77201360Srdivacky case eInstructionTypePCModifying: 78201360Srdivacky return true; 79201360Srdivacky 80201360Srdivacky case eInstructionTypeAll: 81201360Srdivacky return false; 82201360Srdivacky } 83201360Srdivacky return false; 84201360Srdivacky } 85201360Srdivacky 86201360Srdivacky lldb_private::ConstString GetPluginName() override { 87201360Srdivacky return GetPluginNameStatic(); 88201360Srdivacky } 89201360Srdivacky 90201360Srdivacky uint32_t GetPluginVersion() override { return 1; } 91201360Srdivacky 92201360Srdivacky bool SetTargetTriple(const ArchSpec &arch) override; 93201360Srdivacky 94201360Srdivacky enum Mode { eModeInvalid = -1, eModeARM, eModeThumb }; 95201360Srdivacky 96201360Srdivacky EmulateInstructionARM(const ArchSpec &arch) 97201360Srdivacky : EmulateInstruction(arch), m_arm_isa(0), m_opcode_mode(eModeInvalid), 98201360Srdivacky m_opcode_cpsr(0), m_it_session(), m_ignore_conditions(false) { 99201360Srdivacky SetArchitecture(arch); 100201360Srdivacky } 101201360Srdivacky 102201360Srdivacky // EmulateInstructionARM (const ArchSpec &arch, 103201360Srdivacky // bool ignore_conditions, 104201360Srdivacky // void *baton, 105201360Srdivacky // ReadMemory read_mem_callback, 106201360Srdivacky // WriteMemory write_mem_callback, 107201360Srdivacky // ReadRegister read_reg_callback, 108201360Srdivacky // WriteRegister write_reg_callback) : 109201360Srdivacky // EmulateInstruction (arch, 110201360Srdivacky // ignore_conditions, 111201360Srdivacky // baton, 112201360Srdivacky // read_mem_callback, 113201360Srdivacky // write_mem_callback, 114201360Srdivacky // read_reg_callback, 115201360Srdivacky // write_reg_callback), 116201360Srdivacky // m_arm_isa (0), 117201360Srdivacky // m_opcode_mode (eModeInvalid), 118201360Srdivacky // m_opcode_cpsr (0), 119201360Srdivacky // m_it_session () 120201360Srdivacky // { 121201360Srdivacky // } 122201360Srdivacky 123201360Srdivacky bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override { 124201360Srdivacky return SupportsEmulatingInstructionsOfTypeStatic(inst_type); 125201360Srdivacky } 126201360Srdivacky 127201360Srdivacky virtual bool SetArchitecture(const ArchSpec &arch); 128201360Srdivacky 129201360Srdivacky bool ReadInstruction() override; 130201360Srdivacky 131201360Srdivacky bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, 132201360Srdivacky Target *target) override; 133201360Srdivacky 134201360Srdivacky bool EvaluateInstruction(uint32_t evaluate_options) override; 135201360Srdivacky 136201360Srdivacky InstructionCondition GetInstructionCondition() override; 137201360Srdivacky 138201360Srdivacky bool TestEmulation(Stream *out_stream, ArchSpec &arch, 139201360Srdivacky OptionValueDictionary *test_data) override; 140201360Srdivacky 141201360Srdivacky bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num, 142201360Srdivacky RegisterInfo ®_info) override; 143201360Srdivacky 144201360Srdivacky bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override; 145201360Srdivacky 146201360Srdivacky uint32_t ArchVersion(); 147201360Srdivacky 148201360Srdivacky bool ConditionPassed(const uint32_t opcode); 149201360Srdivacky 150201360Srdivacky uint32_t CurrentCond(const uint32_t opcode); 151201360Srdivacky 152201360Srdivacky // InITBlock - Returns true if we're in Thumb mode and inside an IT Block. 153201360Srdivacky bool InITBlock(); 154201360Srdivacky 155201360Srdivacky // LastInITBlock - Returns true if we're in Thumb mode and the last 156201360Srdivacky // instruction inside an IT Block. 157201360Srdivacky bool LastInITBlock(); 158201360Srdivacky 159201360Srdivacky bool BadMode(uint32_t mode); 160201360Srdivacky 161201360Srdivacky bool CurrentModeIsPrivileged(); 162201360Srdivacky 163201360Srdivacky void CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 164218893Sdim bool affect_execstate); 165201360Srdivacky 166201360Srdivacky bool BranchWritePC(const Context &context, uint32_t addr); 167201360Srdivacky 168201360Srdivacky bool BXWritePC(Context &context, uint32_t addr); 169201360Srdivacky 170201360Srdivacky bool LoadWritePC(Context &context, uint32_t addr); 171201360Srdivacky 172201360Srdivacky bool ALUWritePC(Context &context, uint32_t addr); 173201360Srdivacky 174201360Srdivacky Mode CurrentInstrSet(); 175201360Srdivacky 176201360Srdivacky bool SelectInstrSet(Mode arm_or_thumb); 177201360Srdivacky 178201360Srdivacky bool WriteBits32Unknown(int n); 179201360Srdivacky 180201360Srdivacky bool WriteBits32UnknownToMemory(lldb::addr_t address); 181201360Srdivacky 182201360Srdivacky bool UnalignedSupport(); 183201360Srdivacky 184201360Srdivacky typedef struct { 185201360Srdivacky uint32_t result; 186201360Srdivacky uint8_t carry_out; 187201360Srdivacky uint8_t overflow; 188201360Srdivacky } AddWithCarryResult; 189201360Srdivacky 190201360Srdivacky AddWithCarryResult AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in); 191201360Srdivacky 192201360Srdivacky // Helper method to read the content of an ARM core register. 193201360Srdivacky uint32_t ReadCoreReg(uint32_t regnum, bool *success); 194201360Srdivacky 195201360Srdivacky // See A8.6.96 MOV (immediate) Operation. 196201360Srdivacky // Default arguments are specified for carry and overflow parameters, which 197201360Srdivacky // means 198201360Srdivacky // not to update the respective flags even if setflags is true. 199201360Srdivacky bool WriteCoreRegOptionalFlags(Context &context, const uint32_t result, 200201360Srdivacky const uint32_t Rd, bool setflags, 201201360Srdivacky const uint32_t carry = ~0u, 202201360Srdivacky const uint32_t overflow = ~0u); 203201360Srdivacky 204201360Srdivacky bool WriteCoreReg(Context &context, const uint32_t result, 205201360Srdivacky const uint32_t Rd) { 206201360Srdivacky // Don't set the flags. 207201360Srdivacky return WriteCoreRegOptionalFlags(context, result, Rd, false); 208201360Srdivacky } 209201360Srdivacky 210201360Srdivacky // See A8.6.35 CMP (immediate) Operation. 211201360Srdivacky // Default arguments are specified for carry and overflow parameters, which 212201360Srdivacky // means 213201360Srdivacky // not to update the respective flags. 214201360Srdivacky bool WriteFlags(Context &context, const uint32_t result, 215201360Srdivacky const uint32_t carry = ~0u, const uint32_t overflow = ~0u); 216201360Srdivacky 217201360Srdivacky inline uint64_t MemARead(EmulateInstruction::Context &context, 218201360Srdivacky lldb::addr_t address, uint32_t size, 219201360Srdivacky uint64_t fail_value, bool *success_ptr) { 220201360Srdivacky // This is a stub function corresponding to "MemA[]" in the ARM manual 221201360Srdivacky // pseudocode, for 222201360Srdivacky // aligned reads from memory. Since we are not trying to write a full 223201360Srdivacky // hardware simulator, and since 224201360Srdivacky // we are running in User mode (rather than Kernel mode) and therefore won't 225201360Srdivacky // have access to many of the 226201360Srdivacky // system registers we would need in order to fully implement this function, 227201360Srdivacky // we will just call 228201360Srdivacky // ReadMemoryUnsigned from here. In the future, if we decide we do need to 229201360Srdivacky // do more faithful emulation of 230201360Srdivacky // the hardware, we can update this function appropriately. 231201360Srdivacky 232201360Srdivacky return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr); 233201360Srdivacky } 234201360Srdivacky 235201360Srdivacky inline bool MemAWrite(EmulateInstruction::Context &context, 236201360Srdivacky lldb::addr_t address, uint64_t data_val, uint32_t size) 237201360Srdivacky 238201360Srdivacky { 239201360Srdivacky // This is a stub function corresponding to "MemA[]" in the ARM manual 240201360Srdivacky // pseudocode, for 241201360Srdivacky // aligned writes to memory. Since we are not trying to write a full 242201360Srdivacky // hardware simulator, and since 243201360Srdivacky // we are running in User mode (rather than Kernel mode) and therefore won't 244201360Srdivacky // have access to many of the 245201360Srdivacky // system registers we would need in order to fully implement this function, 246201360Srdivacky // we will just call 247201360Srdivacky // WriteMemoryUnsigned from here. In the future, if we decide we do need to 248201360Srdivacky // do more faithful emulation of 249201360Srdivacky // the hardware, we can update this function appropriately. 250201360Srdivacky 251201360Srdivacky return WriteMemoryUnsigned(context, address, data_val, size); 252201360Srdivacky } 253201360Srdivacky 254201360Srdivacky inline uint64_t MemURead(EmulateInstruction::Context &context, 255201360Srdivacky lldb::addr_t address, uint32_t size, 256201360Srdivacky uint64_t fail_value, bool *success_ptr) { 257201360Srdivacky // This is a stub function corresponding to "MemU[]" in the ARM manual 258201360Srdivacky // pseudocode, for 259201360Srdivacky // unaligned reads from memory. Since we are not trying to write a full 260201360Srdivacky // hardware simulator, and since 261201360Srdivacky // we are running in User mode (rather than Kernel mode) and therefore won't 262201360Srdivacky // have access to many of the 263201360Srdivacky // system registers we would need in order to fully implement this function, 264201360Srdivacky // we will just call 265201360Srdivacky // ReadMemoryUnsigned from here. In the future, if we decide we do need to 266201360Srdivacky // do more faithful emulation of 267201360Srdivacky // the hardware, we can update this function appropriately. 268201360Srdivacky 269201360Srdivacky return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr); 270201360Srdivacky } 271201360Srdivacky 272201360Srdivacky inline bool MemUWrite(EmulateInstruction::Context &context, 273201360Srdivacky lldb::addr_t address, uint64_t data_val, uint32_t size) 274201360Srdivacky 275201360Srdivacky { 276201360Srdivacky // This is a stub function corresponding to "MemU[]" in the ARM manual 277201360Srdivacky // pseudocode, for 278218893Sdim // unaligned writes to memory. Since we are not trying to write a full 279201360Srdivacky // hardware simulator, and since 280201360Srdivacky // we are running in User mode (rather than Kernel mode) and therefore won't 281201360Srdivacky // have access to many of the 282201360Srdivacky // system registers we would need in order to fully implement this function, 283201360Srdivacky // we will just call 284201360Srdivacky // WriteMemoryUnsigned from here. In the future, if we decide we do need to 285201360Srdivacky // do more faithful emulation of 286201360Srdivacky // the hardware, we can update this function appropriately. 287201360Srdivacky 288201360Srdivacky return WriteMemoryUnsigned(context, address, data_val, size); 289201360Srdivacky } 290201360Srdivacky 291201360Srdivackyprotected: 292201360Srdivacky // Typedef for the callback function used during the emulation. 293201360Srdivacky // Pass along (ARMEncoding)encoding as the callback data. 294201360Srdivacky enum ARMInstrSize { eSize16, eSize32 }; 295201360Srdivacky 296201360Srdivacky typedef struct { 297201360Srdivacky uint32_t mask; 298201360Srdivacky uint32_t value; 299201360Srdivacky uint32_t variants; 300201360Srdivacky EmulateInstructionARM::ARMEncoding encoding; 301201360Srdivacky uint32_t vfp_variants; 302201360Srdivacky ARMInstrSize size; 303201360Srdivacky bool (EmulateInstructionARM::*callback)( 304201360Srdivacky const uint32_t opcode, 305201360Srdivacky const EmulateInstructionARM::ARMEncoding encoding); 306201360Srdivacky const char *name; 307201360Srdivacky } ARMOpcode; 308201360Srdivacky 309201360Srdivacky uint32_t GetFramePointerRegisterNumber() const; 310201360Srdivacky 311201360Srdivacky uint32_t GetFramePointerDWARFRegisterNumber() const; 312201360Srdivacky 313201360Srdivacky static ARMOpcode *GetARMOpcodeForInstruction(const uint32_t opcode, 314201360Srdivacky uint32_t isa_mask); 315201360Srdivacky 316201360Srdivacky static ARMOpcode *GetThumbOpcodeForInstruction(const uint32_t opcode, 317201360Srdivacky uint32_t isa_mask); 318201360Srdivacky 319201360Srdivacky // A8.6.123 PUSH 320201360Srdivacky bool EmulatePUSH(const uint32_t opcode, const ARMEncoding encoding); 321201360Srdivacky 322201360Srdivacky // A8.6.122 POP 323201360Srdivacky bool EmulatePOP(const uint32_t opcode, const ARMEncoding encoding); 324201360Srdivacky 325201360Srdivacky // A8.6.8 ADD (SP plus immediate) 326201360Srdivacky bool EmulateADDRdSPImm(const uint32_t opcode, const ARMEncoding encoding); 327201360Srdivacky 328201360Srdivacky // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp 329201360Srdivacky bool EmulateMOVRdSP(const uint32_t opcode, const ARMEncoding encoding); 330201360Srdivacky 331201360Srdivacky // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7 332201360Srdivacky bool EmulateMOVLowHigh(const uint32_t opcode, const ARMEncoding encoding); 333201360Srdivacky 334201360Srdivacky // A8.6.59 LDR (literal) 335201360Srdivacky bool EmulateLDRRtPCRelative(const uint32_t opcode, 336201360Srdivacky const ARMEncoding encoding); 337201360Srdivacky 338201360Srdivacky // A8.6.8 ADD (SP plus immediate) 339201360Srdivacky bool EmulateADDSPImm(const uint32_t opcode, const ARMEncoding encoding); 340201360Srdivacky 341201360Srdivacky // A8.6.9 ADD (SP plus register) 342201360Srdivacky bool EmulateADDSPRm(const uint32_t opcode, const ARMEncoding encoding); 343201360Srdivacky 344201360Srdivacky // A8.6.23 BL, BLX (immediate) 345201360Srdivacky bool EmulateBLXImmediate(const uint32_t opcode, const ARMEncoding encoding); 346201360Srdivacky 347201360Srdivacky // A8.6.24 BLX (register) 348201360Srdivacky bool EmulateBLXRm(const uint32_t opcode, const ARMEncoding encoding); 349201360Srdivacky 350201360Srdivacky // A8.6.25 BX 351201360Srdivacky bool EmulateBXRm(const uint32_t opcode, const ARMEncoding encoding); 352201360Srdivacky 353201360Srdivacky // A8.6.26 BXJ 354201360Srdivacky bool EmulateBXJRm(const uint32_t opcode, const ARMEncoding encoding); 355201360Srdivacky 356201360Srdivacky // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip 357201360Srdivacky bool EmulateSUBR7IPImm(const uint32_t opcode, const ARMEncoding encoding); 358201360Srdivacky 359201360Srdivacky // A8.6.215 SUB (SP minus immediate) -- Rd == ip 360201360Srdivacky bool EmulateSUBIPSPImm(const uint32_t opcode, const ARMEncoding encoding); 361201360Srdivacky 362201360Srdivacky // A8.6.215 SUB (SP minus immediate) 363201360Srdivacky bool EmulateSUBSPImm(const uint32_t opcode, const ARMEncoding encoding); 364201360Srdivacky 365201360Srdivacky // A8.6.216 SUB (SP minus register) 366201360Srdivacky bool EmulateSUBSPReg(const uint32_t opcode, const ARMEncoding encoding); 367201360Srdivacky 368218893Sdim // A8.6.194 STR (immediate, ARM) -- Rn == sp 369201360Srdivacky bool EmulateSTRRtSP(const uint32_t opcode, const ARMEncoding encoding); 370201360Srdivacky 371201360Srdivacky // A8.6.355 VPUSH 372201360Srdivacky bool EmulateVPUSH(const uint32_t opcode, const ARMEncoding encoding); 373201360Srdivacky 374201360Srdivacky // A8.6.354 VPOP 375201360Srdivacky bool EmulateVPOP(const uint32_t opcode, const ARMEncoding encoding); 376201360Srdivacky 377201360Srdivacky // A8.6.218 SVC (previously SWI) 378201360Srdivacky bool EmulateSVC(const uint32_t opcode, const ARMEncoding encoding); 379201360Srdivacky 380201360Srdivacky // A8.6.50 IT 381201360Srdivacky bool EmulateIT(const uint32_t opcode, const ARMEncoding encoding); 382201360Srdivacky 383201360Srdivacky // NOP 384201360Srdivacky bool EmulateNop(const uint32_t opcode, const ARMEncoding encoding); 385201360Srdivacky 386201360Srdivacky // A8.6.16 B 387201360Srdivacky bool EmulateB(const uint32_t opcode, const ARMEncoding encoding); 388201360Srdivacky 389201360Srdivacky // A8.6.27 CBNZ, CBZ 390201360Srdivacky bool EmulateCB(const uint32_t opcode, const ARMEncoding encoding); 391201360Srdivacky 392201360Srdivacky // A8.6.226 TBB, TBH 393201360Srdivacky bool EmulateTB(const uint32_t opcode, const ARMEncoding encoding); 394201360Srdivacky 395218893Sdim // A8.6.4 ADD (immediate, Thumb) 396218893Sdim bool EmulateADDImmThumb(const uint32_t opcode, const ARMEncoding encoding); 397201360Srdivacky 398201360Srdivacky // A8.6.5 ADD (immediate, ARM) 399201360Srdivacky bool EmulateADDImmARM(const uint32_t opcode, const ARMEncoding encoding); 400201360Srdivacky 401201360Srdivacky // A8.6.6 ADD (register) 402201360Srdivacky bool EmulateADDReg(const uint32_t opcode, const ARMEncoding encoding); 403201360Srdivacky 404201360Srdivacky // A8.6.7 ADD (register-shifted register) 405201360Srdivacky bool EmulateADDRegShift(const uint32_t opcode, const ARMEncoding encoding); 406201360Srdivacky 407201360Srdivacky // A8.6.97 MOV (register) 408201360Srdivacky bool EmulateMOVRdRm(const uint32_t opcode, const ARMEncoding encoding); 409201360Srdivacky 410201360Srdivacky // A8.6.96 MOV (immediate) 411201360Srdivacky bool EmulateMOVRdImm(const uint32_t opcode, const ARMEncoding encoding); 412201360Srdivacky 413201360Srdivacky // A8.6.35 CMP (immediate) 414201360Srdivacky bool EmulateCMPImm(const uint32_t opcode, const ARMEncoding encoding); 415201360Srdivacky 416201360Srdivacky // A8.6.36 CMP (register) 417201360Srdivacky bool EmulateCMPReg(const uint32_t opcode, const ARMEncoding encoding); 418201360Srdivacky 419201360Srdivacky // A8.6.14 ASR (immediate) 420201360Srdivacky bool EmulateASRImm(const uint32_t opcode, const ARMEncoding encoding); 421201360Srdivacky 422201360Srdivacky // A8.6.15 ASR (register) 423201360Srdivacky bool EmulateASRReg(const uint32_t opcode, const ARMEncoding encoding); 424201360Srdivacky 425201360Srdivacky // A8.6.88 LSL (immediate) 426201360Srdivacky bool EmulateLSLImm(const uint32_t opcode, const ARMEncoding encoding); 427201360Srdivacky 428201360Srdivacky // A8.6.89 LSL (register) 429201360Srdivacky bool EmulateLSLReg(const uint32_t opcode, const ARMEncoding encoding); 430201360Srdivacky 431201360Srdivacky // A8.6.90 LSR (immediate) 432201360Srdivacky bool EmulateLSRImm(const uint32_t opcode, const ARMEncoding encoding); 433201360Srdivacky 434201360Srdivacky // A8.6.91 LSR (register) 435201360Srdivacky bool EmulateLSRReg(const uint32_t opcode, const ARMEncoding encoding); 436201360Srdivacky 437201360Srdivacky // A8.6.139 ROR (immediate) 438201360Srdivacky bool EmulateRORImm(const uint32_t opcode, const ARMEncoding encoding); 439201360Srdivacky 440201360Srdivacky // A8.6.140 ROR (register) 441201360Srdivacky bool EmulateRORReg(const uint32_t opcode, const ARMEncoding encoding); 442201360Srdivacky 443201360Srdivacky // A8.6.141 RRX 444201360Srdivacky bool EmulateRRX(const uint32_t opcode, const ARMEncoding encoding); 445201360Srdivacky 446201360Srdivacky // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX 447201360Srdivacky bool EmulateShiftImm(const uint32_t opcode, const ARMEncoding encoding, 448201360Srdivacky ARM_ShifterType shift_type); 449201360Srdivacky 450201360Srdivacky // Helper method for ASR, LSL, LSR, and ROR (register) 451201360Srdivacky bool EmulateShiftReg(const uint32_t opcode, const ARMEncoding encoding, 452201360Srdivacky ARM_ShifterType shift_type); 453201360Srdivacky 454201360Srdivacky // LOAD FUNCTIONS 455201360Srdivacky 456201360Srdivacky // A8.6.53 LDM/LDMIA/LDMFD 457218893Sdim bool EmulateLDM(const uint32_t opcode, const ARMEncoding encoding); 458218893Sdim 459201360Srdivacky // A8.6.54 LDMDA/LDMFA 460201360Srdivacky bool EmulateLDMDA(const uint32_t opcode, const ARMEncoding encoding); 461201360Srdivacky 462201360Srdivacky // A8.6.55 LDMDB/LDMEA 463201360Srdivacky bool EmulateLDMDB(const uint32_t opcode, const ARMEncoding encoding); 464201360Srdivacky 465201360Srdivacky // A8.6.56 LDMIB/LDMED 466201360Srdivacky bool EmulateLDMIB(const uint32_t opcode, const ARMEncoding encoding); 467201360Srdivacky 468201360Srdivacky // A8.6.57 LDR (immediate, Thumb) -- Encoding T1 469201360Srdivacky bool EmulateLDRRtRnImm(const uint32_t opcode, const ARMEncoding encoding); 470201360Srdivacky 471201360Srdivacky // A8.6.58 LDR (immediate, ARM) - Encoding A1 472201360Srdivacky bool EmulateLDRImmediateARM(const uint32_t opcode, 473201360Srdivacky const ARMEncoding encoding); 474201360Srdivacky 475201360Srdivacky // A8.6.59 LDR (literal) 476201360Srdivacky bool EmulateLDRLiteral(const uint32_t, const ARMEncoding encoding); 477201360Srdivacky 478201360Srdivacky // A8.6.60 LDR (register) - Encoding T1, T2, A1 479201360Srdivacky bool EmulateLDRRegister(const uint32_t opcode, const ARMEncoding encoding); 480201360Srdivacky 481201360Srdivacky // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3 482201360Srdivacky bool EmulateLDRBImmediate(const uint32_t opcode, const ARMEncoding encoding); 483201360Srdivacky 484201360Srdivacky // A8.6.62 LDRB (immediate, ARM) 485201360Srdivacky bool EmulateLDRBImmediateARM(const uint32_t opcode, 486201360Srdivacky const ARMEncoding encoding); 487201360Srdivacky 488201360Srdivacky // A8.6.63 LDRB (literal) - Encoding T1, A1 489201360Srdivacky bool EmulateLDRBLiteral(const uint32_t opcode, const ARMEncoding encoding); 490201360Srdivacky 491201360Srdivacky // A8.6.64 LDRB (register) - Encoding T1, T2, A1 492201360Srdivacky bool EmulateLDRBRegister(const uint32_t opcode, const ARMEncoding encoding); 493201360Srdivacky 494201360Srdivacky // A8.6.65 LDRBT 495201360Srdivacky bool EmulateLDRBT(const uint32_t opcode, const ARMEncoding encoding); 496201360Srdivacky 497201360Srdivacky // A8.6.66 LDRD (immediate) 498201360Srdivacky bool EmulateLDRDImmediate(const uint32_t opcode, const ARMEncoding encoding); 499201360Srdivacky 500201360Srdivacky // A8.6.67 501201360Srdivacky bool EmulateLDRDLiteral(const uint32_t opcode, const ARMEncoding encoding); 502201360Srdivacky 503201360Srdivacky // A8.6.68 LDRD (register) 504201360Srdivacky bool EmulateLDRDRegister(const uint32_t opcode, const ARMEncoding encoding); 505201360Srdivacky 506201360Srdivacky // A8.6.69 LDREX 507201360Srdivacky bool EmulateLDREX(const uint32_t opcode, const ARMEncoding encoding); 508201360Srdivacky 509201360Srdivacky // A8.6.70 LDREXB 510201360Srdivacky bool EmulateLDREXB(const uint32_t opcode, const ARMEncoding encoding); 511201360Srdivacky 512201360Srdivacky // A8.6.71 LDREXD 513201360Srdivacky bool EmulateLDREXD(const uint32_t opcode, const ARMEncoding encoding); 514201360Srdivacky 515201360Srdivacky // A8.6.72 LDREXH 516201360Srdivacky bool EmulateLDREXH(const uint32_t opcode, const ARMEncoding encoding); 517201360Srdivacky 518201360Srdivacky // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3 519201360Srdivacky bool EmulateLDRHImmediate(const uint32_t opcode, const ARMEncoding encoding); 520201360Srdivacky 521201360Srdivacky // A8.6.74 LDRS (immediate, ARM) 522201360Srdivacky bool EmulateLDRHImmediateARM(const uint32_t opcode, 523201360Srdivacky const ARMEncoding encoding); 524201360Srdivacky 525201360Srdivacky // A8.6.75 LDRH (literal) - Encoding T1, A1 526201360Srdivacky bool EmulateLDRHLiteral(const uint32_t opcode, const ARMEncoding encoding); 527201360Srdivacky 528201360Srdivacky // A8.6.76 LDRH (register) - Encoding T1, T2, A1 529201360Srdivacky bool EmulateLDRHRegister(const uint32_t opcode, const ARMEncoding encoding); 530201360Srdivacky 531201360Srdivacky // A8.6.77 LDRHT 532201360Srdivacky bool EmulateLDRHT(const uint32_t opcode, const ARMEncoding encoding); 533201360Srdivacky 534201360Srdivacky // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1 535201360Srdivacky bool EmulateLDRSBImmediate(const uint32_t opcode, const ARMEncoding encoding); 536201360Srdivacky 537201360Srdivacky // A8.6.79 LDRSB (literal) - Encoding T1, A1 538201360Srdivacky bool EmulateLDRSBLiteral(const uint32_t opcode, const ARMEncoding encoding); 539201360Srdivacky 540201360Srdivacky // A8.6.80 LDRSB (register) - Encoding T1, T2, A1 541201360Srdivacky bool EmulateLDRSBRegister(const uint32_t opcode, const ARMEncoding encoding); 542201360Srdivacky 543201360Srdivacky // A8.6.81 LDRSBT 544201360Srdivacky bool EmulateLDRSBT(const uint32_t opcode, const ARMEncoding encoding); 545201360Srdivacky 546201360Srdivacky // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1 547201360Srdivacky bool EmulateLDRSHImmediate(const uint32_t opcode, const ARMEncoding encoding); 548201360Srdivacky 549201360Srdivacky // A8.6.83 LDRSH (literal) - Encoding T1, A1 550201360Srdivacky bool EmulateLDRSHLiteral(const uint32_t opcode, const ARMEncoding encoding); 551201360Srdivacky 552201360Srdivacky // A8.6.84 LDRSH (register) - Encoding T1, T2, A1 553201360Srdivacky bool EmulateLDRSHRegister(const uint32_t opcode, const ARMEncoding encoding); 554201360Srdivacky 555201360Srdivacky // A8.6.85 LDRSHT 556201360Srdivacky bool EmulateLDRSHT(const uint32_t opcode, const ARMEncoding encoding); 557201360Srdivacky 558201360Srdivacky // A8.6.86 559201360Srdivacky bool EmulateLDRT(const uint32_t opcode, const ARMEncoding encoding); 560201360Srdivacky 561201360Srdivacky // STORE FUNCTIONS 562201360Srdivacky 563201360Srdivacky // A8.6.189 STM/STMIA/STMEA 564201360Srdivacky bool EmulateSTM(const uint32_t opcode, const ARMEncoding encoding); 565201360Srdivacky 566201360Srdivacky // A8.6.190 STMDA/STMED 567201360Srdivacky bool EmulateSTMDA(const uint32_t opcode, const ARMEncoding encoding); 568201360Srdivacky 569201360Srdivacky // A8.6.191 STMDB/STMFD 570201360Srdivacky bool EmulateSTMDB(const uint32_t opcode, const ARMEncoding encoding); 571201360Srdivacky 572201360Srdivacky // A8.6.192 STMIB/STMFA 573201360Srdivacky bool EmulateSTMIB(const uint32_t opcode, const ARMEncoding encoding); 574201360Srdivacky 575201360Srdivacky // A8.6.193 STR (immediate, Thumb) 576201360Srdivacky bool EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding); 577201360Srdivacky 578201360Srdivacky // A8.6.194 STR (immediate, ARM) 579201360Srdivacky bool EmulateSTRImmARM(const uint32_t opcode, const ARMEncoding encoding); 580201360Srdivacky 581201360Srdivacky // A8.6.195 STR (register) 582201360Srdivacky bool EmulateSTRRegister(const uint32_t opcode, const ARMEncoding encoding); 583201360Srdivacky 584201360Srdivacky // A8.6.196 STRB (immediate, Thumb) 585201360Srdivacky bool EmulateSTRBThumb(const uint32_t opcode, const ARMEncoding encoding); 586201360Srdivacky 587201360Srdivacky // A8.6.197 STRB (immediate, ARM) 588201360Srdivacky bool EmulateSTRBImmARM(const uint32_t opcode, const ARMEncoding encoding); 589201360Srdivacky 590201360Srdivacky // A8.6.198 STRB (register) 591201360Srdivacky bool EmulateSTRBReg(const uint32_t opcode, const ARMEncoding encoding); 592201360Srdivacky 593201360Srdivacky // A8.6.199 STRBT 594201360Srdivacky bool EmulateSTRBT(const uint32_t opcode, const ARMEncoding encoding); 595201360Srdivacky 596201360Srdivacky // A8.6.200 STRD (immediate) 597201360Srdivacky bool EmulateSTRDImm(const uint32_t opcode, const ARMEncoding encoding); 598201360Srdivacky 599201360Srdivacky // A8.6.201 STRD (register) 600201360Srdivacky bool EmulateSTRDReg(const uint32_t opcode, const ARMEncoding encoding); 601201360Srdivacky 602 // A8.6.202 STREX 603 bool EmulateSTREX(const uint32_t opcode, const ARMEncoding encoding); 604 605 // A8.6.203 STREXB 606 bool EmulateSTREXB(const uint32_t opcode, const ARMEncoding encoding); 607 608 // A8.6.204 STREXD 609 bool EmulateSTREXD(const uint32_t opcode, const ARMEncoding encoding); 610 611 // A8.6.205 STREXH 612 bool EmulateSTREXH(const uint32_t opcode, const ARMEncoding encoding); 613 614 // A8.6.206 STRH (immediate, Thumb) 615 bool EmulateSTRHImmThumb(const uint32_t opcode, const ARMEncoding encoding); 616 617 // A8.6.207 STRH (immediate, ARM) 618 bool EmulateSTRHImmARM(const uint32_t opcode, const ARMEncoding encoding); 619 620 // A8.6.208 STRH (register) 621 bool EmulateSTRHRegister(const uint32_t opcode, const ARMEncoding encoding); 622 623 // A8.6.209 STRHT 624 bool EmulateSTRHT(const uint32_t opcode, const ARMEncoding encoding); 625 626 // A8.6.210 STRT 627 bool EmulateSTRT(const uint32_t opcode, const ARMEncoding encoding); 628 629 // A8.6.1 ADC (immediate) 630 bool EmulateADCImm(const uint32_t opcode, const ARMEncoding encoding); 631 632 // A8.6.2 ADC (Register) 633 bool EmulateADCReg(const uint32_t opcode, const ARMEncoding encoding); 634 635 // A8.6.10 ADR 636 bool EmulateADR(const uint32_t opcode, const ARMEncoding encoding); 637 638 // A8.6.11 AND (immediate) 639 bool EmulateANDImm(const uint32_t opcode, const ARMEncoding encoding); 640 641 // A8.6.12 AND (register) 642 bool EmulateANDReg(const uint32_t opcode, const ARMEncoding encoding); 643 644 // A8.6.19 BIC (immediate) 645 bool EmulateBICImm(const uint32_t opcode, const ARMEncoding encoding); 646 647 // A8.6.20 BIC (register) 648 bool EmulateBICReg(const uint32_t opcode, const ARMEncoding encoding); 649 650 // A8.6.26 BXJ 651 bool EmulateBXJ(const uint32_t opcode, const ARMEncoding encoding); 652 653 // A8.6.32 CMN (immediate) 654 bool EmulateCMNImm(const uint32_t opcode, const ARMEncoding encoding); 655 656 // A8.6.33 CMN (register) 657 bool EmulateCMNReg(const uint32_t opcode, const ARMEncoding encoding); 658 659 // A8.6.44 EOR (immediate) 660 bool EmulateEORImm(const uint32_t opcode, const ARMEncoding encoding); 661 662 // A8.6.45 EOR (register) 663 bool EmulateEORReg(const uint32_t opcode, const ARMEncoding encoding); 664 665 // A8.6.105 MUL 666 bool EmulateMUL(const uint32_t opcode, const ARMEncoding encoding); 667 668 // A8.6.106 MVN (immediate) 669 bool EmulateMVNImm(const uint32_t opcode, const ARMEncoding encoding); 670 671 // A8.6.107 MVN (register) 672 bool EmulateMVNReg(const uint32_t opcode, const ARMEncoding encoding); 673 674 // A8.6.113 ORR (immediate) 675 bool EmulateORRImm(const uint32_t opcode, const ARMEncoding encoding); 676 677 // A8.6.114 ORR (register) 678 bool EmulateORRReg(const uint32_t opcode, const ARMEncoding encoding); 679 680 // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1 681 bool EmulatePLDImmediate(const uint32_t opcode, const ARMEncoding encoding); 682 683 // A8.6.119 PLI (immediate,literal) - Encoding T3, A1 684 bool EmulatePLIImmediate(const uint32_t opcode, const ARMEncoding encoding); 685 686 // A8.6.120 PLI (register) - Encoding T1, A1 687 bool EmulatePLIRegister(const uint32_t opcode, const ARMEncoding encoding); 688 689 // A8.6.141 RSB (immediate) 690 bool EmulateRSBImm(const uint32_t opcode, const ARMEncoding encoding); 691 692 // A8.6.142 RSB (register) 693 bool EmulateRSBReg(const uint32_t opcode, const ARMEncoding encoding); 694 695 // A8.6.144 RSC (immediate) 696 bool EmulateRSCImm(const uint32_t opcode, const ARMEncoding encoding); 697 698 // A8.6.145 RSC (register) 699 bool EmulateRSCReg(const uint32_t opcode, const ARMEncoding encoding); 700 701 // A8.6.150 SBC (immediate) 702 bool EmulateSBCImm(const uint32_t opcode, const ARMEncoding encoding); 703 704 // A8.6.151 SBC (register) 705 bool EmulateSBCReg(const uint32_t opcode, const ARMEncoding encoding); 706 707 // A8.6.211 SUB (immediate, Thumb) 708 bool EmulateSUBImmThumb(const uint32_t opcode, const ARMEncoding encoding); 709 710 // A8.6.212 SUB (immediate, ARM) 711 bool EmulateSUBImmARM(const uint32_t opcode, const ARMEncoding encoding); 712 713 // A8.6.213 SUB (register) 714 bool EmulateSUBReg(const uint32_t opcode, const ARMEncoding encoding); 715 716 // A8.6.214 SUB (register-shifted register) 717 bool EmulateSUBRegShift(const uint32_t opcode, const ARMEncoding encoding); 718 719 // A8.6.222 SXTB - Encoding T1 720 bool EmulateSXTB(const uint32_t opcode, const ARMEncoding encoding); 721 722 // A8.6.224 SXTH - EncodingT1 723 bool EmulateSXTH(const uint32_t opcode, const ARMEncoding encoding); 724 725 // A8.6.227 TEQ (immediate) - Encoding A1 726 bool EmulateTEQImm(const uint32_t opcode, const ARMEncoding encoding); 727 728 // A8.6.228 TEQ (register) - Encoding A1 729 bool EmulateTEQReg(const uint32_t opcode, const ARMEncoding encoding); 730 731 // A8.6.230 TST (immediate) - Encoding A1 732 bool EmulateTSTImm(const uint32_t opcode, const ARMEncoding encoding); 733 734 // A8.6.231 TST (register) - Encoding T1, A1 735 bool EmulateTSTReg(const uint32_t opcode, const ARMEncoding encoding); 736 737 // A8.6.262 UXTB - Encoding T1 738 bool EmulateUXTB(const uint32_t opcode, const ARMEncoding encoding); 739 740 // A8.6.264 UXTH - Encoding T1 741 bool EmulateUXTH(const uint32_t opcode, const ARMEncoding encoding); 742 743 // B6.1.8 RFE 744 bool EmulateRFE(const uint32_t opcode, const ARMEncoding encoding); 745 746 // A8.6.319 VLDM 747 bool EmulateVLDM(const uint32_t opcode, const ARMEncoding encoding); 748 749 // A8.6.399 VSTM 750 bool EmulateVSTM(const uint32_t opcode, const ARMEncoding encoding); 751 752 // A8.6.307 VLD1 (multiple single elements) 753 bool EmulateVLD1Multiple(const uint32_t opcode, const ARMEncoding encoding); 754 755 // A8.6.308 VLD1 (single element to one lane) 756 bool EmulateVLD1Single(const uint32_t opcode, const ARMEncoding encoding); 757 758 // A8.6.309 VLD1 (single element to all lanes) 759 bool EmulateVLD1SingleAll(const uint32_t opcode, const ARMEncoding encoding); 760 761 // A8.6.391 VST1 (multiple single elements) 762 bool EmulateVST1Multiple(const uint32_t opcode, const ARMEncoding encoding); 763 764 // A8.6.392 VST1 (single element from one lane) 765 bool EmulateVST1Single(const uint32_t opcode, const ARMEncoding encoding); 766 767 // A8.6.317 VLDR 768 bool EmulateVLDR(const uint32_t opcode, const ARMEncoding encoding); 769 770 // A8.6.400 VSTR 771 bool EmulateVSTR(const uint32_t opcode, const ARMEncoding encoding); 772 773 // B6.2.13 SUBS PC, LR and related instructions 774 bool EmulateSUBSPcLrEtc(const uint32_t opcode, const ARMEncoding encoding); 775 776 uint32_t m_arm_isa; 777 Mode m_opcode_mode; 778 uint32_t m_opcode_cpsr; 779 uint32_t m_new_inst_cpsr; // This can get updated by the opcode. 780 ITSession m_it_session; 781 bool m_ignore_conditions; 782}; 783 784} // namespace lldb_private 785 786#endif // lldb_EmulateInstructionARM_h_ 787