/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- EmulateInstructionARM.h ---------------------------------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H |
10 | | #define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H |
11 | | |
12 | | #include "Plugins/Process/Utility/ARMDefines.h" |
13 | | #include "lldb/Core/EmulateInstruction.h" |
14 | | #include "lldb/Utility/Status.h" |
15 | | #include <optional> |
16 | | |
17 | | namespace lldb_private { |
18 | | |
19 | | // ITSession - Keep track of the IT Block progression. |
20 | | class ITSession { |
21 | | public: |
22 | 164 | ITSession() = default; |
23 | | ~ITSession() = default; |
24 | | |
25 | | // InitIT - Initializes ITCounter/ITState. |
26 | | bool InitIT(uint32_t bits7_0); |
27 | | |
28 | | // ITAdvance - Updates ITCounter/ITState as IT Block progresses. |
29 | | void ITAdvance(); |
30 | | |
31 | | // InITBlock - Returns true if we're inside an IT Block. |
32 | | bool InITBlock(); |
33 | | |
34 | | // LastInITBlock - Returns true if we're the last instruction inside an IT |
35 | | // Block. |
36 | | bool LastInITBlock(); |
37 | | |
38 | | // GetCond - Gets condition bits for the current thumb instruction. |
39 | | uint32_t GetCond(); |
40 | | |
41 | | private: |
42 | | uint32_t ITCounter = 0; // Possible values: 0, 1, 2, 3, 4. |
43 | | uint32_t ITState = 0; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. |
44 | | }; |
45 | | |
46 | | class EmulateInstructionARM : public EmulateInstruction { |
47 | | public: |
48 | | enum ARMEncoding { |
49 | | eEncodingA1, |
50 | | eEncodingA2, |
51 | | eEncodingA3, |
52 | | eEncodingA4, |
53 | | eEncodingA5, |
54 | | eEncodingT1, |
55 | | eEncodingT2, |
56 | | eEncodingT3, |
57 | | eEncodingT4, |
58 | | eEncodingT5 |
59 | | }; |
60 | | |
61 | | static void Initialize(); |
62 | | |
63 | | static void Terminate(); |
64 | | |
65 | 3.92k | static llvm::StringRef GetPluginNameStatic() { return "arm"; } |
66 | | |
67 | | static llvm::StringRef GetPluginDescriptionStatic(); |
68 | | |
69 | | static lldb_private::EmulateInstruction * |
70 | | CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type); |
71 | | |
72 | | static bool |
73 | 16.9k | SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type) { |
74 | 16.9k | switch (inst_type) { |
75 | 160 | case eInstructionTypeAny: |
76 | 16.9k | case eInstructionTypePrologueEpilogue: |
77 | 16.9k | case eInstructionTypePCModifying: |
78 | 16.9k | return true; |
79 | | |
80 | 0 | case eInstructionTypeAll: |
81 | 0 | return false; |
82 | 16.9k | } |
83 | 0 | return false; |
84 | 16.9k | } |
85 | | |
86 | 0 | llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } |
87 | | |
88 | | bool SetTargetTriple(const ArchSpec &arch) override; |
89 | | |
90 | | enum Mode { eModeInvalid = -1, eModeARM, eModeThumb }; |
91 | | |
92 | | EmulateInstructionARM(const ArchSpec &arch) |
93 | 164 | : EmulateInstruction(arch), m_arm_isa(0), m_opcode_mode(eModeInvalid), |
94 | 164 | m_opcode_cpsr(0), m_new_inst_cpsr(0), m_it_session(), |
95 | 164 | m_ignore_conditions(false) { |
96 | 164 | SetArchitecture(arch); |
97 | 164 | } |
98 | | |
99 | | // EmulateInstructionARM (const ArchSpec &arch, |
100 | | // bool ignore_conditions, |
101 | | // void *baton, |
102 | | // ReadMemory read_mem_callback, |
103 | | // WriteMemory write_mem_callback, |
104 | | // ReadRegister read_reg_callback, |
105 | | // WriteRegister write_reg_callback) : |
106 | | // EmulateInstruction (arch, |
107 | | // ignore_conditions, |
108 | | // baton, |
109 | | // read_mem_callback, |
110 | | // write_mem_callback, |
111 | | // read_reg_callback, |
112 | | // write_reg_callback), |
113 | | // m_arm_isa (0), |
114 | | // m_opcode_mode (eModeInvalid), |
115 | | // m_opcode_cpsr (0), |
116 | | // m_it_session () |
117 | | // { |
118 | | // } |
119 | | |
120 | 0 | bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override { |
121 | 0 | return SupportsEmulatingInstructionsOfTypeStatic(inst_type); |
122 | 0 | } |
123 | | |
124 | | virtual bool SetArchitecture(const ArchSpec &arch); |
125 | | |
126 | | bool ReadInstruction() override; |
127 | | |
128 | | bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, |
129 | | Target *target) override; |
130 | | |
131 | | bool EvaluateInstruction(uint32_t evaluate_options) override; |
132 | | |
133 | | InstructionCondition GetInstructionCondition() override; |
134 | | |
135 | | bool TestEmulation(Stream &out_stream, ArchSpec &arch, |
136 | | OptionValueDictionary *test_data) override; |
137 | | |
138 | | std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind, |
139 | | uint32_t reg_num) override; |
140 | | |
141 | | bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override; |
142 | | |
143 | | uint32_t ArchVersion(); |
144 | | |
145 | | bool ConditionPassed(const uint32_t opcode); |
146 | | |
147 | | uint32_t CurrentCond(const uint32_t opcode); |
148 | | |
149 | | // InITBlock - Returns true if we're in Thumb mode and inside an IT Block. |
150 | | bool InITBlock(); |
151 | | |
152 | | // LastInITBlock - Returns true if we're in Thumb mode and the last |
153 | | // instruction inside an IT Block. |
154 | | bool LastInITBlock(); |
155 | | |
156 | | bool BadMode(uint32_t mode); |
157 | | |
158 | | bool CurrentModeIsPrivileged(); |
159 | | |
160 | | void CPSRWriteByInstr(uint32_t value, uint32_t bytemask, |
161 | | bool affect_execstate); |
162 | | |
163 | | bool BranchWritePC(const Context &context, uint32_t addr); |
164 | | |
165 | | bool BXWritePC(Context &context, uint32_t addr); |
166 | | |
167 | | bool LoadWritePC(Context &context, uint32_t addr); |
168 | | |
169 | | bool ALUWritePC(Context &context, uint32_t addr); |
170 | | |
171 | | Mode CurrentInstrSet(); |
172 | | |
173 | | bool SelectInstrSet(Mode arm_or_thumb); |
174 | | |
175 | | bool WriteBits32Unknown(int n); |
176 | | |
177 | | bool WriteBits32UnknownToMemory(lldb::addr_t address); |
178 | | |
179 | | bool UnalignedSupport(); |
180 | | |
181 | | typedef struct { |
182 | | uint32_t result; |
183 | | uint8_t carry_out; |
184 | | uint8_t overflow; |
185 | | } AddWithCarryResult; |
186 | | |
187 | | AddWithCarryResult AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in); |
188 | | |
189 | | // Helper method to read the content of an ARM core register. |
190 | | uint32_t ReadCoreReg(uint32_t regnum, bool *success); |
191 | | |
192 | | // See A8.6.96 MOV (immediate) Operation. |
193 | | // Default arguments are specified for carry and overflow parameters, which |
194 | | // means |
195 | | // not to update the respective flags even if setflags is true. |
196 | | bool WriteCoreRegOptionalFlags(Context &context, const uint32_t result, |
197 | | const uint32_t Rd, bool setflags, |
198 | | const uint32_t carry = ~0u, |
199 | | const uint32_t overflow = ~0u); |
200 | | |
201 | | bool WriteCoreReg(Context &context, const uint32_t result, |
202 | 0 | const uint32_t Rd) { |
203 | | // Don't set the flags. |
204 | 0 | return WriteCoreRegOptionalFlags(context, result, Rd, false); |
205 | 0 | } |
206 | | |
207 | | // See A8.6.35 CMP (immediate) Operation. |
208 | | // Default arguments are specified for carry and overflow parameters, which |
209 | | // means |
210 | | // not to update the respective flags. |
211 | | bool WriteFlags(Context &context, const uint32_t result, |
212 | | const uint32_t carry = ~0u, const uint32_t overflow = ~0u); |
213 | | |
214 | | inline uint64_t MemARead(EmulateInstruction::Context &context, |
215 | | lldb::addr_t address, uint32_t size, |
216 | 52 | uint64_t fail_value, bool *success_ptr) { |
217 | | // This is a stub function corresponding to "MemA[]" in the ARM manual |
218 | | // pseudocode, for |
219 | | // aligned reads from memory. Since we are not trying to write a full |
220 | | // hardware simulator, and since |
221 | | // we are running in User mode (rather than Kernel mode) and therefore won't |
222 | | // have access to many of the |
223 | | // system registers we would need in order to fully implement this function, |
224 | | // we will just call |
225 | | // ReadMemoryUnsigned from here. In the future, if we decide we do need to |
226 | | // do more faithful emulation of |
227 | | // the hardware, we can update this function appropriately. |
228 | | |
229 | 52 | return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr); |
230 | 52 | } |
231 | | |
232 | | inline bool MemAWrite(EmulateInstruction::Context &context, |
233 | | lldb::addr_t address, uint64_t data_val, uint32_t size) |
234 | | |
235 | 39 | { |
236 | | // This is a stub function corresponding to "MemA[]" in the ARM manual |
237 | | // pseudocode, for |
238 | | // aligned writes to memory. Since we are not trying to write a full |
239 | | // hardware simulator, and since |
240 | | // we are running in User mode (rather than Kernel mode) and therefore won't |
241 | | // have access to many of the |
242 | | // system registers we would need in order to fully implement this function, |
243 | | // we will just call |
244 | | // WriteMemoryUnsigned from here. In the future, if we decide we do need to |
245 | | // do more faithful emulation of |
246 | | // the hardware, we can update this function appropriately. |
247 | | |
248 | 39 | return WriteMemoryUnsigned(context, address, data_val, size); |
249 | 39 | } |
250 | | |
251 | | inline uint64_t MemURead(EmulateInstruction::Context &context, |
252 | | lldb::addr_t address, uint32_t size, |
253 | 23 | uint64_t fail_value, bool *success_ptr) { |
254 | | // This is a stub function corresponding to "MemU[]" in the ARM manual |
255 | | // pseudocode, for |
256 | | // unaligned reads from memory. Since we are not trying to write a full |
257 | | // hardware simulator, and since |
258 | | // we are running in User mode (rather than Kernel mode) and therefore won't |
259 | | // have access to many of the |
260 | | // system registers we would need in order to fully implement this function, |
261 | | // we will just call |
262 | | // ReadMemoryUnsigned from here. In the future, if we decide we do need to |
263 | | // do more faithful emulation of |
264 | | // the hardware, we can update this function appropriately. |
265 | | |
266 | 23 | return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr); |
267 | 23 | } |
268 | | |
269 | | inline bool MemUWrite(EmulateInstruction::Context &context, |
270 | | lldb::addr_t address, uint64_t data_val, uint32_t size) |
271 | | |
272 | 13 | { |
273 | | // This is a stub function corresponding to "MemU[]" in the ARM manual |
274 | | // pseudocode, for |
275 | | // unaligned writes to memory. Since we are not trying to write a full |
276 | | // hardware simulator, and since |
277 | | // we are running in User mode (rather than Kernel mode) and therefore won't |
278 | | // have access to many of the |
279 | | // system registers we would need in order to fully implement this function, |
280 | | // we will just call |
281 | | // WriteMemoryUnsigned from here. In the future, if we decide we do need to |
282 | | // do more faithful emulation of |
283 | | // the hardware, we can update this function appropriately. |
284 | | |
285 | 13 | return WriteMemoryUnsigned(context, address, data_val, size); |
286 | 13 | } |
287 | | |
288 | | protected: |
289 | | // Typedef for the callback function used during the emulation. |
290 | | // Pass along (ARMEncoding)encoding as the callback data. |
291 | | enum ARMInstrSize { eSize16, eSize32 }; |
292 | | |
293 | | typedef struct { |
294 | | uint32_t mask; |
295 | | uint32_t value; |
296 | | uint32_t variants; |
297 | | EmulateInstructionARM::ARMEncoding encoding; |
298 | | uint32_t vfp_variants; |
299 | | ARMInstrSize size; |
300 | | bool (EmulateInstructionARM::*callback)( |
301 | | const uint32_t opcode, |
302 | | const EmulateInstructionARM::ARMEncoding encoding); |
303 | | const char *name; |
304 | | } ARMOpcode; |
305 | | |
306 | | uint32_t GetFramePointerRegisterNumber() const; |
307 | | |
308 | | uint32_t GetFramePointerDWARFRegisterNumber() const; |
309 | | |
310 | | static ARMOpcode *GetARMOpcodeForInstruction(const uint32_t opcode, |
311 | | uint32_t isa_mask); |
312 | | |
313 | | static ARMOpcode *GetThumbOpcodeForInstruction(const uint32_t opcode, |
314 | | uint32_t isa_mask); |
315 | | |
316 | | // A8.6.123 PUSH |
317 | | bool EmulatePUSH(const uint32_t opcode, const ARMEncoding encoding); |
318 | | |
319 | | // A8.6.122 POP |
320 | | bool EmulatePOP(const uint32_t opcode, const ARMEncoding encoding); |
321 | | |
322 | | // A8.6.8 ADD (SP plus immediate) |
323 | | bool EmulateADDRdSPImm(const uint32_t opcode, const ARMEncoding encoding); |
324 | | |
325 | | // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp |
326 | | bool EmulateMOVRdSP(const uint32_t opcode, const ARMEncoding encoding); |
327 | | |
328 | | // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7 |
329 | | bool EmulateMOVLowHigh(const uint32_t opcode, const ARMEncoding encoding); |
330 | | |
331 | | // A8.6.59 LDR (literal) |
332 | | bool EmulateLDRRtPCRelative(const uint32_t opcode, |
333 | | const ARMEncoding encoding); |
334 | | |
335 | | // A8.6.8 ADD (SP plus immediate) |
336 | | bool EmulateADDSPImm(const uint32_t opcode, const ARMEncoding encoding); |
337 | | |
338 | | // A8.6.9 ADD (SP plus register) |
339 | | bool EmulateADDSPRm(const uint32_t opcode, const ARMEncoding encoding); |
340 | | |
341 | | // A8.6.23 BL, BLX (immediate) |
342 | | bool EmulateBLXImmediate(const uint32_t opcode, const ARMEncoding encoding); |
343 | | |
344 | | // A8.6.24 BLX (register) |
345 | | bool EmulateBLXRm(const uint32_t opcode, const ARMEncoding encoding); |
346 | | |
347 | | // A8.6.25 BX |
348 | | bool EmulateBXRm(const uint32_t opcode, const ARMEncoding encoding); |
349 | | |
350 | | // A8.6.26 BXJ |
351 | | bool EmulateBXJRm(const uint32_t opcode, const ARMEncoding encoding); |
352 | | |
353 | | // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip |
354 | | bool EmulateSUBR7IPImm(const uint32_t opcode, const ARMEncoding encoding); |
355 | | |
356 | | // A8.6.215 SUB (SP minus immediate) -- Rd == ip |
357 | | bool EmulateSUBIPSPImm(const uint32_t opcode, const ARMEncoding encoding); |
358 | | |
359 | | // A8.6.215 SUB (SP minus immediate) |
360 | | bool EmulateSUBSPImm(const uint32_t opcode, const ARMEncoding encoding); |
361 | | |
362 | | // A8.6.216 SUB (SP minus register) |
363 | | bool EmulateSUBSPReg(const uint32_t opcode, const ARMEncoding encoding); |
364 | | |
365 | | // A8.6.194 STR (immediate, ARM) -- Rn == sp |
366 | | bool EmulateSTRRtSP(const uint32_t opcode, const ARMEncoding encoding); |
367 | | |
368 | | // A8.6.355 VPUSH |
369 | | bool EmulateVPUSH(const uint32_t opcode, const ARMEncoding encoding); |
370 | | |
371 | | // A8.6.354 VPOP |
372 | | bool EmulateVPOP(const uint32_t opcode, const ARMEncoding encoding); |
373 | | |
374 | | // A8.6.218 SVC (previously SWI) |
375 | | bool EmulateSVC(const uint32_t opcode, const ARMEncoding encoding); |
376 | | |
377 | | // A8.6.50 IT |
378 | | bool EmulateIT(const uint32_t opcode, const ARMEncoding encoding); |
379 | | |
380 | | // NOP |
381 | | bool EmulateNop(const uint32_t opcode, const ARMEncoding encoding); |
382 | | |
383 | | // A8.6.16 B |
384 | | bool EmulateB(const uint32_t opcode, const ARMEncoding encoding); |
385 | | |
386 | | // A8.6.27 CBNZ, CBZ |
387 | | bool EmulateCB(const uint32_t opcode, const ARMEncoding encoding); |
388 | | |
389 | | // A8.6.226 TBB, TBH |
390 | | bool EmulateTB(const uint32_t opcode, const ARMEncoding encoding); |
391 | | |
392 | | // A8.6.4 ADD (immediate, Thumb) |
393 | | bool EmulateADDImmThumb(const uint32_t opcode, const ARMEncoding encoding); |
394 | | |
395 | | // A8.6.5 ADD (immediate, ARM) |
396 | | bool EmulateADDImmARM(const uint32_t opcode, const ARMEncoding encoding); |
397 | | |
398 | | // A8.6.6 ADD (register) |
399 | | bool EmulateADDReg(const uint32_t opcode, const ARMEncoding encoding); |
400 | | |
401 | | // A8.6.7 ADD (register-shifted register) |
402 | | bool EmulateADDRegShift(const uint32_t opcode, const ARMEncoding encoding); |
403 | | |
404 | | // A8.6.97 MOV (register) |
405 | | bool EmulateMOVRdRm(const uint32_t opcode, const ARMEncoding encoding); |
406 | | |
407 | | // A8.6.96 MOV (immediate) |
408 | | bool EmulateMOVRdImm(const uint32_t opcode, const ARMEncoding encoding); |
409 | | |
410 | | // A8.6.35 CMP (immediate) |
411 | | bool EmulateCMPImm(const uint32_t opcode, const ARMEncoding encoding); |
412 | | |
413 | | // A8.6.36 CMP (register) |
414 | | bool EmulateCMPReg(const uint32_t opcode, const ARMEncoding encoding); |
415 | | |
416 | | // A8.6.14 ASR (immediate) |
417 | | bool EmulateASRImm(const uint32_t opcode, const ARMEncoding encoding); |
418 | | |
419 | | // A8.6.15 ASR (register) |
420 | | bool EmulateASRReg(const uint32_t opcode, const ARMEncoding encoding); |
421 | | |
422 | | // A8.6.88 LSL (immediate) |
423 | | bool EmulateLSLImm(const uint32_t opcode, const ARMEncoding encoding); |
424 | | |
425 | | // A8.6.89 LSL (register) |
426 | | bool EmulateLSLReg(const uint32_t opcode, const ARMEncoding encoding); |
427 | | |
428 | | // A8.6.90 LSR (immediate) |
429 | | bool EmulateLSRImm(const uint32_t opcode, const ARMEncoding encoding); |
430 | | |
431 | | // A8.6.91 LSR (register) |
432 | | bool EmulateLSRReg(const uint32_t opcode, const ARMEncoding encoding); |
433 | | |
434 | | // A8.6.139 ROR (immediate) |
435 | | bool EmulateRORImm(const uint32_t opcode, const ARMEncoding encoding); |
436 | | |
437 | | // A8.6.140 ROR (register) |
438 | | bool EmulateRORReg(const uint32_t opcode, const ARMEncoding encoding); |
439 | | |
440 | | // A8.6.141 RRX |
441 | | bool EmulateRRX(const uint32_t opcode, const ARMEncoding encoding); |
442 | | |
443 | | // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX |
444 | | bool EmulateShiftImm(const uint32_t opcode, const ARMEncoding encoding, |
445 | | ARM_ShifterType shift_type); |
446 | | |
447 | | // Helper method for ASR, LSL, LSR, and ROR (register) |
448 | | bool EmulateShiftReg(const uint32_t opcode, const ARMEncoding encoding, |
449 | | ARM_ShifterType shift_type); |
450 | | |
451 | | // LOAD FUNCTIONS |
452 | | |
453 | | // A8.6.53 LDM/LDMIA/LDMFD |
454 | | bool EmulateLDM(const uint32_t opcode, const ARMEncoding encoding); |
455 | | |
456 | | // A8.6.54 LDMDA/LDMFA |
457 | | bool EmulateLDMDA(const uint32_t opcode, const ARMEncoding encoding); |
458 | | |
459 | | // A8.6.55 LDMDB/LDMEA |
460 | | bool EmulateLDMDB(const uint32_t opcode, const ARMEncoding encoding); |
461 | | |
462 | | // A8.6.56 LDMIB/LDMED |
463 | | bool EmulateLDMIB(const uint32_t opcode, const ARMEncoding encoding); |
464 | | |
465 | | // A8.6.57 LDR (immediate, Thumb) -- Encoding T1 |
466 | | bool EmulateLDRRtRnImm(const uint32_t opcode, const ARMEncoding encoding); |
467 | | |
468 | | // A8.6.58 LDR (immediate, ARM) - Encoding A1 |
469 | | bool EmulateLDRImmediateARM(const uint32_t opcode, |
470 | | const ARMEncoding encoding); |
471 | | |
472 | | // A8.6.59 LDR (literal) |
473 | | bool EmulateLDRLiteral(const uint32_t, const ARMEncoding encoding); |
474 | | |
475 | | // A8.6.60 LDR (register) - Encoding T1, T2, A1 |
476 | | bool EmulateLDRRegister(const uint32_t opcode, const ARMEncoding encoding); |
477 | | |
478 | | // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3 |
479 | | bool EmulateLDRBImmediate(const uint32_t opcode, const ARMEncoding encoding); |
480 | | |
481 | | // A8.6.62 LDRB (immediate, ARM) |
482 | | bool EmulateLDRBImmediateARM(const uint32_t opcode, |
483 | | const ARMEncoding encoding); |
484 | | |
485 | | // A8.6.63 LDRB (literal) - Encoding T1, A1 |
486 | | bool EmulateLDRBLiteral(const uint32_t opcode, const ARMEncoding encoding); |
487 | | |
488 | | // A8.6.64 LDRB (register) - Encoding T1, T2, A1 |
489 | | bool EmulateLDRBRegister(const uint32_t opcode, const ARMEncoding encoding); |
490 | | |
491 | | // A8.6.65 LDRBT |
492 | | bool EmulateLDRBT(const uint32_t opcode, const ARMEncoding encoding); |
493 | | |
494 | | // A8.6.66 LDRD (immediate) |
495 | | bool EmulateLDRDImmediate(const uint32_t opcode, const ARMEncoding encoding); |
496 | | |
497 | | // A8.6.67 |
498 | | bool EmulateLDRDLiteral(const uint32_t opcode, const ARMEncoding encoding); |
499 | | |
500 | | // A8.6.68 LDRD (register) |
501 | | bool EmulateLDRDRegister(const uint32_t opcode, const ARMEncoding encoding); |
502 | | |
503 | | // A8.6.69 LDREX |
504 | | bool EmulateLDREX(const uint32_t opcode, const ARMEncoding encoding); |
505 | | |
506 | | // A8.6.70 LDREXB |
507 | | bool EmulateLDREXB(const uint32_t opcode, const ARMEncoding encoding); |
508 | | |
509 | | // A8.6.71 LDREXD |
510 | | bool EmulateLDREXD(const uint32_t opcode, const ARMEncoding encoding); |
511 | | |
512 | | // A8.6.72 LDREXH |
513 | | bool EmulateLDREXH(const uint32_t opcode, const ARMEncoding encoding); |
514 | | |
515 | | // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3 |
516 | | bool EmulateLDRHImmediate(const uint32_t opcode, const ARMEncoding encoding); |
517 | | |
518 | | // A8.6.74 LDRS (immediate, ARM) |
519 | | bool EmulateLDRHImmediateARM(const uint32_t opcode, |
520 | | const ARMEncoding encoding); |
521 | | |
522 | | // A8.6.75 LDRH (literal) - Encoding T1, A1 |
523 | | bool EmulateLDRHLiteral(const uint32_t opcode, const ARMEncoding encoding); |
524 | | |
525 | | // A8.6.76 LDRH (register) - Encoding T1, T2, A1 |
526 | | bool EmulateLDRHRegister(const uint32_t opcode, const ARMEncoding encoding); |
527 | | |
528 | | // A8.6.77 LDRHT |
529 | | bool EmulateLDRHT(const uint32_t opcode, const ARMEncoding encoding); |
530 | | |
531 | | // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1 |
532 | | bool EmulateLDRSBImmediate(const uint32_t opcode, const ARMEncoding encoding); |
533 | | |
534 | | // A8.6.79 LDRSB (literal) - Encoding T1, A1 |
535 | | bool EmulateLDRSBLiteral(const uint32_t opcode, const ARMEncoding encoding); |
536 | | |
537 | | // A8.6.80 LDRSB (register) - Encoding T1, T2, A1 |
538 | | bool EmulateLDRSBRegister(const uint32_t opcode, const ARMEncoding encoding); |
539 | | |
540 | | // A8.6.81 LDRSBT |
541 | | bool EmulateLDRSBT(const uint32_t opcode, const ARMEncoding encoding); |
542 | | |
543 | | // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1 |
544 | | bool EmulateLDRSHImmediate(const uint32_t opcode, const ARMEncoding encoding); |
545 | | |
546 | | // A8.6.83 LDRSH (literal) - Encoding T1, A1 |
547 | | bool EmulateLDRSHLiteral(const uint32_t opcode, const ARMEncoding encoding); |
548 | | |
549 | | // A8.6.84 LDRSH (register) - Encoding T1, T2, A1 |
550 | | bool EmulateLDRSHRegister(const uint32_t opcode, const ARMEncoding encoding); |
551 | | |
552 | | // A8.6.85 LDRSHT |
553 | | bool EmulateLDRSHT(const uint32_t opcode, const ARMEncoding encoding); |
554 | | |
555 | | // A8.6.86 |
556 | | bool EmulateLDRT(const uint32_t opcode, const ARMEncoding encoding); |
557 | | |
558 | | // STORE FUNCTIONS |
559 | | |
560 | | // A8.6.189 STM/STMIA/STMEA |
561 | | bool EmulateSTM(const uint32_t opcode, const ARMEncoding encoding); |
562 | | |
563 | | // A8.6.190 STMDA/STMED |
564 | | bool EmulateSTMDA(const uint32_t opcode, const ARMEncoding encoding); |
565 | | |
566 | | // A8.6.191 STMDB/STMFD |
567 | | bool EmulateSTMDB(const uint32_t opcode, const ARMEncoding encoding); |
568 | | |
569 | | // A8.6.192 STMIB/STMFA |
570 | | bool EmulateSTMIB(const uint32_t opcode, const ARMEncoding encoding); |
571 | | |
572 | | // A8.6.193 STR (immediate, Thumb) |
573 | | bool EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding); |
574 | | |
575 | | // A8.6.194 STR (immediate, ARM) |
576 | | bool EmulateSTRImmARM(const uint32_t opcode, const ARMEncoding encoding); |
577 | | |
578 | | // A8.6.195 STR (register) |
579 | | bool EmulateSTRRegister(const uint32_t opcode, const ARMEncoding encoding); |
580 | | |
581 | | // A8.6.196 STRB (immediate, Thumb) |
582 | | bool EmulateSTRBThumb(const uint32_t opcode, const ARMEncoding encoding); |
583 | | |
584 | | // A8.6.197 STRB (immediate, ARM) |
585 | | bool EmulateSTRBImmARM(const uint32_t opcode, const ARMEncoding encoding); |
586 | | |
587 | | // A8.6.198 STRB (register) |
588 | | bool EmulateSTRBReg(const uint32_t opcode, const ARMEncoding encoding); |
589 | | |
590 | | // A8.6.199 STRBT |
591 | | bool EmulateSTRBT(const uint32_t opcode, const ARMEncoding encoding); |
592 | | |
593 | | // A8.6.200 STRD (immediate) |
594 | | bool EmulateSTRDImm(const uint32_t opcode, const ARMEncoding encoding); |
595 | | |
596 | | // A8.6.201 STRD (register) |
597 | | bool EmulateSTRDReg(const uint32_t opcode, const ARMEncoding encoding); |
598 | | |
599 | | // A8.6.202 STREX |
600 | | bool EmulateSTREX(const uint32_t opcode, const ARMEncoding encoding); |
601 | | |
602 | | // A8.6.203 STREXB |
603 | | bool EmulateSTREXB(const uint32_t opcode, const ARMEncoding encoding); |
604 | | |
605 | | // A8.6.204 STREXD |
606 | | bool EmulateSTREXD(const uint32_t opcode, const ARMEncoding encoding); |
607 | | |
608 | | // A8.6.205 STREXH |
609 | | bool EmulateSTREXH(const uint32_t opcode, const ARMEncoding encoding); |
610 | | |
611 | | // A8.6.206 STRH (immediate, Thumb) |
612 | | bool EmulateSTRHImmThumb(const uint32_t opcode, const ARMEncoding encoding); |
613 | | |
614 | | // A8.6.207 STRH (immediate, ARM) |
615 | | bool EmulateSTRHImmARM(const uint32_t opcode, const ARMEncoding encoding); |
616 | | |
617 | | // A8.6.208 STRH (register) |
618 | | bool EmulateSTRHRegister(const uint32_t opcode, const ARMEncoding encoding); |
619 | | |
620 | | // A8.6.209 STRHT |
621 | | bool EmulateSTRHT(const uint32_t opcode, const ARMEncoding encoding); |
622 | | |
623 | | // A8.6.210 STRT |
624 | | bool EmulateSTRT(const uint32_t opcode, const ARMEncoding encoding); |
625 | | |
626 | | // A8.6.1 ADC (immediate) |
627 | | bool EmulateADCImm(const uint32_t opcode, const ARMEncoding encoding); |
628 | | |
629 | | // A8.6.2 ADC (Register) |
630 | | bool EmulateADCReg(const uint32_t opcode, const ARMEncoding encoding); |
631 | | |
632 | | // A8.6.10 ADR |
633 | | bool EmulateADR(const uint32_t opcode, const ARMEncoding encoding); |
634 | | |
635 | | // A8.6.11 AND (immediate) |
636 | | bool EmulateANDImm(const uint32_t opcode, const ARMEncoding encoding); |
637 | | |
638 | | // A8.6.12 AND (register) |
639 | | bool EmulateANDReg(const uint32_t opcode, const ARMEncoding encoding); |
640 | | |
641 | | // A8.6.19 BIC (immediate) |
642 | | bool EmulateBICImm(const uint32_t opcode, const ARMEncoding encoding); |
643 | | |
644 | | // A8.6.20 BIC (register) |
645 | | bool EmulateBICReg(const uint32_t opcode, const ARMEncoding encoding); |
646 | | |
647 | | // A8.6.26 BXJ |
648 | | bool EmulateBXJ(const uint32_t opcode, const ARMEncoding encoding); |
649 | | |
650 | | // A8.6.32 CMN (immediate) |
651 | | bool EmulateCMNImm(const uint32_t opcode, const ARMEncoding encoding); |
652 | | |
653 | | // A8.6.33 CMN (register) |
654 | | bool EmulateCMNReg(const uint32_t opcode, const ARMEncoding encoding); |
655 | | |
656 | | // A8.6.44 EOR (immediate) |
657 | | bool EmulateEORImm(const uint32_t opcode, const ARMEncoding encoding); |
658 | | |
659 | | // A8.6.45 EOR (register) |
660 | | bool EmulateEORReg(const uint32_t opcode, const ARMEncoding encoding); |
661 | | |
662 | | // A8.6.105 MUL |
663 | | bool EmulateMUL(const uint32_t opcode, const ARMEncoding encoding); |
664 | | |
665 | | // A8.6.106 MVN (immediate) |
666 | | bool EmulateMVNImm(const uint32_t opcode, const ARMEncoding encoding); |
667 | | |
668 | | // A8.6.107 MVN (register) |
669 | | bool EmulateMVNReg(const uint32_t opcode, const ARMEncoding encoding); |
670 | | |
671 | | // A8.6.113 ORR (immediate) |
672 | | bool EmulateORRImm(const uint32_t opcode, const ARMEncoding encoding); |
673 | | |
674 | | // A8.6.114 ORR (register) |
675 | | bool EmulateORRReg(const uint32_t opcode, const ARMEncoding encoding); |
676 | | |
677 | | // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1 |
678 | | bool EmulatePLDImmediate(const uint32_t opcode, const ARMEncoding encoding); |
679 | | |
680 | | // A8.6.119 PLI (immediate,literal) - Encoding T3, A1 |
681 | | bool EmulatePLIImmediate(const uint32_t opcode, const ARMEncoding encoding); |
682 | | |
683 | | // A8.6.120 PLI (register) - Encoding T1, A1 |
684 | | bool EmulatePLIRegister(const uint32_t opcode, const ARMEncoding encoding); |
685 | | |
686 | | // A8.6.141 RSB (immediate) |
687 | | bool EmulateRSBImm(const uint32_t opcode, const ARMEncoding encoding); |
688 | | |
689 | | // A8.6.142 RSB (register) |
690 | | bool EmulateRSBReg(const uint32_t opcode, const ARMEncoding encoding); |
691 | | |
692 | | // A8.6.144 RSC (immediate) |
693 | | bool EmulateRSCImm(const uint32_t opcode, const ARMEncoding encoding); |
694 | | |
695 | | // A8.6.145 RSC (register) |
696 | | bool EmulateRSCReg(const uint32_t opcode, const ARMEncoding encoding); |
697 | | |
698 | | // A8.6.150 SBC (immediate) |
699 | | bool EmulateSBCImm(const uint32_t opcode, const ARMEncoding encoding); |
700 | | |
701 | | // A8.6.151 SBC (register) |
702 | | bool EmulateSBCReg(const uint32_t opcode, const ARMEncoding encoding); |
703 | | |
704 | | // A8.6.211 SUB (immediate, Thumb) |
705 | | bool EmulateSUBImmThumb(const uint32_t opcode, const ARMEncoding encoding); |
706 | | |
707 | | // A8.6.212 SUB (immediate, ARM) |
708 | | bool EmulateSUBImmARM(const uint32_t opcode, const ARMEncoding encoding); |
709 | | |
710 | | // A8.6.213 SUB (register) |
711 | | bool EmulateSUBReg(const uint32_t opcode, const ARMEncoding encoding); |
712 | | |
713 | | // A8.6.214 SUB (register-shifted register) |
714 | | bool EmulateSUBRegShift(const uint32_t opcode, const ARMEncoding encoding); |
715 | | |
716 | | // A8.6.222 SXTB - Encoding T1 |
717 | | bool EmulateSXTB(const uint32_t opcode, const ARMEncoding encoding); |
718 | | |
719 | | // A8.6.224 SXTH - EncodingT1 |
720 | | bool EmulateSXTH(const uint32_t opcode, const ARMEncoding encoding); |
721 | | |
722 | | // A8.6.227 TEQ (immediate) - Encoding A1 |
723 | | bool EmulateTEQImm(const uint32_t opcode, const ARMEncoding encoding); |
724 | | |
725 | | // A8.6.228 TEQ (register) - Encoding A1 |
726 | | bool EmulateTEQReg(const uint32_t opcode, const ARMEncoding encoding); |
727 | | |
728 | | // A8.6.230 TST (immediate) - Encoding A1 |
729 | | bool EmulateTSTImm(const uint32_t opcode, const ARMEncoding encoding); |
730 | | |
731 | | // A8.6.231 TST (register) - Encoding T1, A1 |
732 | | bool EmulateTSTReg(const uint32_t opcode, const ARMEncoding encoding); |
733 | | |
734 | | // A8.6.262 UXTB - Encoding T1 |
735 | | bool EmulateUXTB(const uint32_t opcode, const ARMEncoding encoding); |
736 | | |
737 | | // A8.6.264 UXTH - Encoding T1 |
738 | | bool EmulateUXTH(const uint32_t opcode, const ARMEncoding encoding); |
739 | | |
740 | | // B6.1.8 RFE |
741 | | bool EmulateRFE(const uint32_t opcode, const ARMEncoding encoding); |
742 | | |
743 | | // A8.6.319 VLDM |
744 | | bool EmulateVLDM(const uint32_t opcode, const ARMEncoding encoding); |
745 | | |
746 | | // A8.6.399 VSTM |
747 | | bool EmulateVSTM(const uint32_t opcode, const ARMEncoding encoding); |
748 | | |
749 | | // A8.6.307 VLD1 (multiple single elements) |
750 | | bool EmulateVLD1Multiple(const uint32_t opcode, const ARMEncoding encoding); |
751 | | |
752 | | // A8.6.308 VLD1 (single element to one lane) |
753 | | bool EmulateVLD1Single(const uint32_t opcode, const ARMEncoding encoding); |
754 | | |
755 | | // A8.6.309 VLD1 (single element to all lanes) |
756 | | bool EmulateVLD1SingleAll(const uint32_t opcode, const ARMEncoding encoding); |
757 | | |
758 | | // A8.6.391 VST1 (multiple single elements) |
759 | | bool EmulateVST1Multiple(const uint32_t opcode, const ARMEncoding encoding); |
760 | | |
761 | | // A8.6.392 VST1 (single element from one lane) |
762 | | bool EmulateVST1Single(const uint32_t opcode, const ARMEncoding encoding); |
763 | | |
764 | | // A8.6.317 VLDR |
765 | | bool EmulateVLDR(const uint32_t opcode, const ARMEncoding encoding); |
766 | | |
767 | | // A8.6.400 VSTR |
768 | | bool EmulateVSTR(const uint32_t opcode, const ARMEncoding encoding); |
769 | | |
770 | | // B6.2.13 SUBS PC, LR and related instructions |
771 | | bool EmulateSUBSPcLrEtc(const uint32_t opcode, const ARMEncoding encoding); |
772 | | |
773 | | uint32_t m_arm_isa; |
774 | | Mode m_opcode_mode; |
775 | | uint32_t m_opcode_cpsr; |
776 | | uint32_t m_new_inst_cpsr; // This can get updated by the opcode. |
777 | | ITSession m_it_session; |
778 | | bool m_ignore_conditions; |
779 | | }; |
780 | | |
781 | | } // namespace lldb_private |
782 | | |
783 | | #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H |