1//===-- EmulateInstructionARM.cpp -----------------------------------------===//
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#include <cstdlib>
10#include <optional>
11
12#include "EmulateInstructionARM.h"
13#include "EmulationStateARM.h"
14#include "lldb/Core/Address.h"
15#include "lldb/Core/PluginManager.h"
16#include "lldb/Host/PosixApi.h"
17#include "lldb/Interpreter/OptionValueArray.h"
18#include "lldb/Interpreter/OptionValueDictionary.h"
19#include "lldb/Symbol/UnwindPlan.h"
20#include "lldb/Utility/ArchSpec.h"
21#include "lldb/Utility/Stream.h"
22
23#include "Plugins/Process/Utility/ARMDefines.h"
24#include "Plugins/Process/Utility/ARMUtils.h"
25#include "Utility/ARM_DWARF_Registers.h"
26
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/Support/MathExtras.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM, InstructionARM)
34
35// Convenient macro definitions.
36#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
37#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
38
39#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
40
41//
42// ITSession implementation
43//
44
45static std::optional<RegisterInfo> GetARMDWARFRegisterInfo(unsigned reg_num) {
46  RegisterInfo reg_info;
47  ::memset(&reg_info, 0, sizeof(RegisterInfo));
48  ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
49
50  if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
51    reg_info.byte_size = 16;
52    reg_info.format = eFormatVectorOfUInt8;
53    reg_info.encoding = eEncodingVector;
54  }
55
56  if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
57    reg_info.byte_size = 8;
58    reg_info.format = eFormatFloat;
59    reg_info.encoding = eEncodingIEEE754;
60  } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
61    reg_info.byte_size = 4;
62    reg_info.format = eFormatFloat;
63    reg_info.encoding = eEncodingIEEE754;
64  } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
65    reg_info.byte_size = 12;
66    reg_info.format = eFormatFloat;
67    reg_info.encoding = eEncodingIEEE754;
68  } else {
69    reg_info.byte_size = 4;
70    reg_info.format = eFormatHex;
71    reg_info.encoding = eEncodingUint;
72  }
73
74  reg_info.kinds[eRegisterKindDWARF] = reg_num;
75
76  switch (reg_num) {
77  case dwarf_r0:
78    reg_info.name = "r0";
79    break;
80  case dwarf_r1:
81    reg_info.name = "r1";
82    break;
83  case dwarf_r2:
84    reg_info.name = "r2";
85    break;
86  case dwarf_r3:
87    reg_info.name = "r3";
88    break;
89  case dwarf_r4:
90    reg_info.name = "r4";
91    break;
92  case dwarf_r5:
93    reg_info.name = "r5";
94    break;
95  case dwarf_r6:
96    reg_info.name = "r6";
97    break;
98  case dwarf_r7:
99    reg_info.name = "r7";
100    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
101    break;
102  case dwarf_r8:
103    reg_info.name = "r8";
104    break;
105  case dwarf_r9:
106    reg_info.name = "r9";
107    break;
108  case dwarf_r10:
109    reg_info.name = "r10";
110    break;
111  case dwarf_r11:
112    reg_info.name = "r11";
113    break;
114  case dwarf_r12:
115    reg_info.name = "r12";
116    break;
117  case dwarf_sp:
118    reg_info.name = "sp";
119    reg_info.alt_name = "r13";
120    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
121    break;
122  case dwarf_lr:
123    reg_info.name = "lr";
124    reg_info.alt_name = "r14";
125    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
126    break;
127  case dwarf_pc:
128    reg_info.name = "pc";
129    reg_info.alt_name = "r15";
130    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
131    break;
132  case dwarf_cpsr:
133    reg_info.name = "cpsr";
134    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
135    break;
136
137  case dwarf_s0:
138    reg_info.name = "s0";
139    break;
140  case dwarf_s1:
141    reg_info.name = "s1";
142    break;
143  case dwarf_s2:
144    reg_info.name = "s2";
145    break;
146  case dwarf_s3:
147    reg_info.name = "s3";
148    break;
149  case dwarf_s4:
150    reg_info.name = "s4";
151    break;
152  case dwarf_s5:
153    reg_info.name = "s5";
154    break;
155  case dwarf_s6:
156    reg_info.name = "s6";
157    break;
158  case dwarf_s7:
159    reg_info.name = "s7";
160    break;
161  case dwarf_s8:
162    reg_info.name = "s8";
163    break;
164  case dwarf_s9:
165    reg_info.name = "s9";
166    break;
167  case dwarf_s10:
168    reg_info.name = "s10";
169    break;
170  case dwarf_s11:
171    reg_info.name = "s11";
172    break;
173  case dwarf_s12:
174    reg_info.name = "s12";
175    break;
176  case dwarf_s13:
177    reg_info.name = "s13";
178    break;
179  case dwarf_s14:
180    reg_info.name = "s14";
181    break;
182  case dwarf_s15:
183    reg_info.name = "s15";
184    break;
185  case dwarf_s16:
186    reg_info.name = "s16";
187    break;
188  case dwarf_s17:
189    reg_info.name = "s17";
190    break;
191  case dwarf_s18:
192    reg_info.name = "s18";
193    break;
194  case dwarf_s19:
195    reg_info.name = "s19";
196    break;
197  case dwarf_s20:
198    reg_info.name = "s20";
199    break;
200  case dwarf_s21:
201    reg_info.name = "s21";
202    break;
203  case dwarf_s22:
204    reg_info.name = "s22";
205    break;
206  case dwarf_s23:
207    reg_info.name = "s23";
208    break;
209  case dwarf_s24:
210    reg_info.name = "s24";
211    break;
212  case dwarf_s25:
213    reg_info.name = "s25";
214    break;
215  case dwarf_s26:
216    reg_info.name = "s26";
217    break;
218  case dwarf_s27:
219    reg_info.name = "s27";
220    break;
221  case dwarf_s28:
222    reg_info.name = "s28";
223    break;
224  case dwarf_s29:
225    reg_info.name = "s29";
226    break;
227  case dwarf_s30:
228    reg_info.name = "s30";
229    break;
230  case dwarf_s31:
231    reg_info.name = "s31";
232    break;
233
234  // FPA Registers 0-7
235  case dwarf_f0:
236    reg_info.name = "f0";
237    break;
238  case dwarf_f1:
239    reg_info.name = "f1";
240    break;
241  case dwarf_f2:
242    reg_info.name = "f2";
243    break;
244  case dwarf_f3:
245    reg_info.name = "f3";
246    break;
247  case dwarf_f4:
248    reg_info.name = "f4";
249    break;
250  case dwarf_f5:
251    reg_info.name = "f5";
252    break;
253  case dwarf_f6:
254    reg_info.name = "f6";
255    break;
256  case dwarf_f7:
257    reg_info.name = "f7";
258    break;
259
260  // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
261  // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
262  case dwarf_wCGR0:
263    reg_info.name = "wCGR0/ACC0";
264    break;
265  case dwarf_wCGR1:
266    reg_info.name = "wCGR1/ACC1";
267    break;
268  case dwarf_wCGR2:
269    reg_info.name = "wCGR2/ACC2";
270    break;
271  case dwarf_wCGR3:
272    reg_info.name = "wCGR3/ACC3";
273    break;
274  case dwarf_wCGR4:
275    reg_info.name = "wCGR4/ACC4";
276    break;
277  case dwarf_wCGR5:
278    reg_info.name = "wCGR5/ACC5";
279    break;
280  case dwarf_wCGR6:
281    reg_info.name = "wCGR6/ACC6";
282    break;
283  case dwarf_wCGR7:
284    reg_info.name = "wCGR7/ACC7";
285    break;
286
287  // Intel wireless MMX data registers 0 - 15
288  case dwarf_wR0:
289    reg_info.name = "wR0";
290    break;
291  case dwarf_wR1:
292    reg_info.name = "wR1";
293    break;
294  case dwarf_wR2:
295    reg_info.name = "wR2";
296    break;
297  case dwarf_wR3:
298    reg_info.name = "wR3";
299    break;
300  case dwarf_wR4:
301    reg_info.name = "wR4";
302    break;
303  case dwarf_wR5:
304    reg_info.name = "wR5";
305    break;
306  case dwarf_wR6:
307    reg_info.name = "wR6";
308    break;
309  case dwarf_wR7:
310    reg_info.name = "wR7";
311    break;
312  case dwarf_wR8:
313    reg_info.name = "wR8";
314    break;
315  case dwarf_wR9:
316    reg_info.name = "wR9";
317    break;
318  case dwarf_wR10:
319    reg_info.name = "wR10";
320    break;
321  case dwarf_wR11:
322    reg_info.name = "wR11";
323    break;
324  case dwarf_wR12:
325    reg_info.name = "wR12";
326    break;
327  case dwarf_wR13:
328    reg_info.name = "wR13";
329    break;
330  case dwarf_wR14:
331    reg_info.name = "wR14";
332    break;
333  case dwarf_wR15:
334    reg_info.name = "wR15";
335    break;
336
337  case dwarf_spsr:
338    reg_info.name = "spsr";
339    break;
340  case dwarf_spsr_fiq:
341    reg_info.name = "spsr_fiq";
342    break;
343  case dwarf_spsr_irq:
344    reg_info.name = "spsr_irq";
345    break;
346  case dwarf_spsr_abt:
347    reg_info.name = "spsr_abt";
348    break;
349  case dwarf_spsr_und:
350    reg_info.name = "spsr_und";
351    break;
352  case dwarf_spsr_svc:
353    reg_info.name = "spsr_svc";
354    break;
355
356  case dwarf_r8_usr:
357    reg_info.name = "r8_usr";
358    break;
359  case dwarf_r9_usr:
360    reg_info.name = "r9_usr";
361    break;
362  case dwarf_r10_usr:
363    reg_info.name = "r10_usr";
364    break;
365  case dwarf_r11_usr:
366    reg_info.name = "r11_usr";
367    break;
368  case dwarf_r12_usr:
369    reg_info.name = "r12_usr";
370    break;
371  case dwarf_r13_usr:
372    reg_info.name = "r13_usr";
373    break;
374  case dwarf_r14_usr:
375    reg_info.name = "r14_usr";
376    break;
377  case dwarf_r8_fiq:
378    reg_info.name = "r8_fiq";
379    break;
380  case dwarf_r9_fiq:
381    reg_info.name = "r9_fiq";
382    break;
383  case dwarf_r10_fiq:
384    reg_info.name = "r10_fiq";
385    break;
386  case dwarf_r11_fiq:
387    reg_info.name = "r11_fiq";
388    break;
389  case dwarf_r12_fiq:
390    reg_info.name = "r12_fiq";
391    break;
392  case dwarf_r13_fiq:
393    reg_info.name = "r13_fiq";
394    break;
395  case dwarf_r14_fiq:
396    reg_info.name = "r14_fiq";
397    break;
398  case dwarf_r13_irq:
399    reg_info.name = "r13_irq";
400    break;
401  case dwarf_r14_irq:
402    reg_info.name = "r14_irq";
403    break;
404  case dwarf_r13_abt:
405    reg_info.name = "r13_abt";
406    break;
407  case dwarf_r14_abt:
408    reg_info.name = "r14_abt";
409    break;
410  case dwarf_r13_und:
411    reg_info.name = "r13_und";
412    break;
413  case dwarf_r14_und:
414    reg_info.name = "r14_und";
415    break;
416  case dwarf_r13_svc:
417    reg_info.name = "r13_svc";
418    break;
419  case dwarf_r14_svc:
420    reg_info.name = "r14_svc";
421    break;
422
423  // Intel wireless MMX control register in co-processor 0 - 7
424  case dwarf_wC0:
425    reg_info.name = "wC0";
426    break;
427  case dwarf_wC1:
428    reg_info.name = "wC1";
429    break;
430  case dwarf_wC2:
431    reg_info.name = "wC2";
432    break;
433  case dwarf_wC3:
434    reg_info.name = "wC3";
435    break;
436  case dwarf_wC4:
437    reg_info.name = "wC4";
438    break;
439  case dwarf_wC5:
440    reg_info.name = "wC5";
441    break;
442  case dwarf_wC6:
443    reg_info.name = "wC6";
444    break;
445  case dwarf_wC7:
446    reg_info.name = "wC7";
447    break;
448
449  // VFP-v3/Neon
450  case dwarf_d0:
451    reg_info.name = "d0";
452    break;
453  case dwarf_d1:
454    reg_info.name = "d1";
455    break;
456  case dwarf_d2:
457    reg_info.name = "d2";
458    break;
459  case dwarf_d3:
460    reg_info.name = "d3";
461    break;
462  case dwarf_d4:
463    reg_info.name = "d4";
464    break;
465  case dwarf_d5:
466    reg_info.name = "d5";
467    break;
468  case dwarf_d6:
469    reg_info.name = "d6";
470    break;
471  case dwarf_d7:
472    reg_info.name = "d7";
473    break;
474  case dwarf_d8:
475    reg_info.name = "d8";
476    break;
477  case dwarf_d9:
478    reg_info.name = "d9";
479    break;
480  case dwarf_d10:
481    reg_info.name = "d10";
482    break;
483  case dwarf_d11:
484    reg_info.name = "d11";
485    break;
486  case dwarf_d12:
487    reg_info.name = "d12";
488    break;
489  case dwarf_d13:
490    reg_info.name = "d13";
491    break;
492  case dwarf_d14:
493    reg_info.name = "d14";
494    break;
495  case dwarf_d15:
496    reg_info.name = "d15";
497    break;
498  case dwarf_d16:
499    reg_info.name = "d16";
500    break;
501  case dwarf_d17:
502    reg_info.name = "d17";
503    break;
504  case dwarf_d18:
505    reg_info.name = "d18";
506    break;
507  case dwarf_d19:
508    reg_info.name = "d19";
509    break;
510  case dwarf_d20:
511    reg_info.name = "d20";
512    break;
513  case dwarf_d21:
514    reg_info.name = "d21";
515    break;
516  case dwarf_d22:
517    reg_info.name = "d22";
518    break;
519  case dwarf_d23:
520    reg_info.name = "d23";
521    break;
522  case dwarf_d24:
523    reg_info.name = "d24";
524    break;
525  case dwarf_d25:
526    reg_info.name = "d25";
527    break;
528  case dwarf_d26:
529    reg_info.name = "d26";
530    break;
531  case dwarf_d27:
532    reg_info.name = "d27";
533    break;
534  case dwarf_d28:
535    reg_info.name = "d28";
536    break;
537  case dwarf_d29:
538    reg_info.name = "d29";
539    break;
540  case dwarf_d30:
541    reg_info.name = "d30";
542    break;
543  case dwarf_d31:
544    reg_info.name = "d31";
545    break;
546
547  // NEON 128-bit vector registers (overlays the d registers)
548  case dwarf_q0:
549    reg_info.name = "q0";
550    break;
551  case dwarf_q1:
552    reg_info.name = "q1";
553    break;
554  case dwarf_q2:
555    reg_info.name = "q2";
556    break;
557  case dwarf_q3:
558    reg_info.name = "q3";
559    break;
560  case dwarf_q4:
561    reg_info.name = "q4";
562    break;
563  case dwarf_q5:
564    reg_info.name = "q5";
565    break;
566  case dwarf_q6:
567    reg_info.name = "q6";
568    break;
569  case dwarf_q7:
570    reg_info.name = "q7";
571    break;
572  case dwarf_q8:
573    reg_info.name = "q8";
574    break;
575  case dwarf_q9:
576    reg_info.name = "q9";
577    break;
578  case dwarf_q10:
579    reg_info.name = "q10";
580    break;
581  case dwarf_q11:
582    reg_info.name = "q11";
583    break;
584  case dwarf_q12:
585    reg_info.name = "q12";
586    break;
587  case dwarf_q13:
588    reg_info.name = "q13";
589    break;
590  case dwarf_q14:
591    reg_info.name = "q14";
592    break;
593  case dwarf_q15:
594    reg_info.name = "q15";
595    break;
596
597  default:
598    return {};
599  }
600  return reg_info;
601}
602
603// A8.6.50
604// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
605static uint32_t CountITSize(uint32_t ITMask) {
606  // First count the trailing zeros of the IT mask.
607  uint32_t TZ = llvm::countr_zero(ITMask);
608  if (TZ > 3) {
609    return 0;
610  }
611  return (4 - TZ);
612}
613
614// Init ITState.  Note that at least one bit is always 1 in mask.
615bool ITSession::InitIT(uint32_t bits7_0) {
616  ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
617  if (ITCounter == 0)
618    return false;
619
620  // A8.6.50 IT
621  unsigned short FirstCond = Bits32(bits7_0, 7, 4);
622  if (FirstCond == 0xF) {
623    return false;
624  }
625  if (FirstCond == 0xE && ITCounter != 1) {
626    return false;
627  }
628
629  ITState = bits7_0;
630  return true;
631}
632
633// Update ITState if necessary.
634void ITSession::ITAdvance() {
635  // assert(ITCounter);
636  --ITCounter;
637  if (ITCounter == 0)
638    ITState = 0;
639  else {
640    unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
641    SetBits32(ITState, 4, 0, NewITState4_0);
642  }
643}
644
645// Return true if we're inside an IT Block.
646bool ITSession::InITBlock() { return ITCounter != 0; }
647
648// Return true if we're the last instruction inside an IT Block.
649bool ITSession::LastInITBlock() { return ITCounter == 1; }
650
651// Get condition bits for the current thumb instruction.
652uint32_t ITSession::GetCond() {
653  if (InITBlock())
654    return Bits32(ITState, 7, 4);
655  else
656    return COND_AL;
657}
658
659// ARM constants used during decoding
660#define REG_RD 0
661#define LDM_REGLIST 1
662#define SP_REG 13
663#define LR_REG 14
664#define PC_REG 15
665#define PC_REGLIST_BIT 0x8000
666
667#define ARMv4 (1u << 0)
668#define ARMv4T (1u << 1)
669#define ARMv5T (1u << 2)
670#define ARMv5TE (1u << 3)
671#define ARMv5TEJ (1u << 4)
672#define ARMv6 (1u << 5)
673#define ARMv6K (1u << 6)
674#define ARMv6T2 (1u << 7)
675#define ARMv7 (1u << 8)
676#define ARMv7S (1u << 9)
677#define ARMv8 (1u << 10)
678#define ARMvAll (0xffffffffu)
679
680#define ARMV4T_ABOVE                                                           \
681  (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 |   \
682   ARMv7S | ARMv8)
683#define ARMV5_ABOVE                                                            \
684  (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S |   \
685   ARMv8)
686#define ARMV5TE_ABOVE                                                          \
687  (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
688#define ARMV5J_ABOVE                                                           \
689  (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
690#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
691#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
692#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
693
694#define No_VFP 0
695#define VFPv1 (1u << 1)
696#define VFPv2 (1u << 2)
697#define VFPv3 (1u << 3)
698#define AdvancedSIMD (1u << 4)
699
700#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
701#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
702#define VFPv2v3 (VFPv2 | VFPv3)
703
704//
705// EmulateInstructionARM implementation
706//
707
708void EmulateInstructionARM::Initialize() {
709  PluginManager::RegisterPlugin(GetPluginNameStatic(),
710                                GetPluginDescriptionStatic(), CreateInstance);
711}
712
713void EmulateInstructionARM::Terminate() {
714  PluginManager::UnregisterPlugin(CreateInstance);
715}
716
717llvm::StringRef EmulateInstructionARM::GetPluginDescriptionStatic() {
718  return "Emulate instructions for the ARM architecture.";
719}
720
721EmulateInstruction *
722EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
723                                      InstructionType inst_type) {
724  if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
725          inst_type)) {
726    if (arch.GetTriple().getArch() == llvm::Triple::arm) {
727      std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
728          new EmulateInstructionARM(arch));
729
730      if (emulate_insn_up)
731        return emulate_insn_up.release();
732    } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
733      std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
734          new EmulateInstructionARM(arch));
735
736      if (emulate_insn_up)
737        return emulate_insn_up.release();
738    }
739  }
740
741  return nullptr;
742}
743
744bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
745  if (arch.GetTriple().getArch() == llvm::Triple::arm)
746    return true;
747  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
748    return true;
749
750  return false;
751}
752
753// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for
754// many ARM instructions.
755bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
756  EmulateInstruction::Context context;
757  context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
758  context.SetNoArgs();
759
760  uint32_t random_data = rand();
761  const uint32_t addr_byte_size = GetAddressByteSize();
762
763  return MemAWrite(context, address, random_data, addr_byte_size);
764}
765
766// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM
767// instructions.
768bool EmulateInstructionARM::WriteBits32Unknown(int n) {
769  EmulateInstruction::Context context;
770  context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
771  context.SetNoArgs();
772
773  bool success;
774  uint32_t data =
775      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
776
777  if (!success)
778    return false;
779
780  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
781    return false;
782
783  return true;
784}
785
786std::optional<RegisterInfo>
787EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
788                                       uint32_t reg_num) {
789  if (reg_kind == eRegisterKindGeneric) {
790    switch (reg_num) {
791    case LLDB_REGNUM_GENERIC_PC:
792      reg_kind = eRegisterKindDWARF;
793      reg_num = dwarf_pc;
794      break;
795    case LLDB_REGNUM_GENERIC_SP:
796      reg_kind = eRegisterKindDWARF;
797      reg_num = dwarf_sp;
798      break;
799    case LLDB_REGNUM_GENERIC_FP:
800      reg_kind = eRegisterKindDWARF;
801      reg_num = dwarf_r7;
802      break;
803    case LLDB_REGNUM_GENERIC_RA:
804      reg_kind = eRegisterKindDWARF;
805      reg_num = dwarf_lr;
806      break;
807    case LLDB_REGNUM_GENERIC_FLAGS:
808      reg_kind = eRegisterKindDWARF;
809      reg_num = dwarf_cpsr;
810      break;
811    default:
812      return {};
813    }
814  }
815
816  if (reg_kind == eRegisterKindDWARF)
817    return GetARMDWARFRegisterInfo(reg_num);
818  return {};
819}
820
821uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
822  if (m_arch.GetTriple().isAndroid())
823    return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
824  bool is_apple = false;
825  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
826    is_apple = true;
827  switch (m_arch.GetTriple().getOS()) {
828  case llvm::Triple::Darwin:
829  case llvm::Triple::MacOSX:
830  case llvm::Triple::IOS:
831  case llvm::Triple::TvOS:
832  case llvm::Triple::WatchOS:
833  case llvm::Triple::XROS:
834  // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
835    is_apple = true;
836    break;
837  default:
838    break;
839  }
840
841  /* On Apple iOS et al, the frame pointer register is always r7.
842   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
843   * Windows on ARM, which is in thumb mode, uses r11 though.
844   */
845
846  uint32_t fp_regnum = 11;
847
848  if (is_apple)
849    fp_regnum = 7;
850
851  if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
852    fp_regnum = 7;
853
854  return fp_regnum;
855}
856
857uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
858  bool is_apple = false;
859  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
860    is_apple = true;
861  switch (m_arch.GetTriple().getOS()) {
862  case llvm::Triple::Darwin:
863  case llvm::Triple::MacOSX:
864  case llvm::Triple::IOS:
865    is_apple = true;
866    break;
867  default:
868    break;
869  }
870
871  /* On Apple iOS et al, the frame pointer register is always r7.
872   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
873   * Windows on ARM, which is in thumb mode, uses r11 though.
874   */
875
876  uint32_t fp_regnum = dwarf_r11;
877
878  if (is_apple)
879    fp_regnum = dwarf_r7;
880
881  if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
882    fp_regnum = dwarf_r7;
883
884  return fp_regnum;
885}
886
887// Push Multiple Registers stores multiple registers to the stack, storing to
888// consecutive memory locations ending just below the address in SP, and
889// updates
890// SP to point to the start of the stored data.
891bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
892                                        const ARMEncoding encoding) {
893#if 0
894    // ARM pseudo code...
895    if (ConditionPassed())
896    {
897        EncodingSpecificOperations();
898        NullCheckIfThumbEE(13);
899        address = SP - 4*BitCount(registers);
900
901        for (i = 0 to 14)
902        {
903            if (registers<i> == '1')
904            {
905                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
906                    MemA[address,4] = bits(32) UNKNOWN;
907                else
908                    MemA[address,4] = R[i];
909                address = address + 4;
910            }
911        }
912
913        if (registers<15> == '1') // Only possible for encoding A1 or A2
914            MemA[address,4] = PCStoreValue();
915
916        SP = SP - 4*BitCount(registers);
917    }
918#endif
919
920  bool success = false;
921  if (ConditionPassed(opcode)) {
922    const uint32_t addr_byte_size = GetAddressByteSize();
923    const addr_t sp = ReadCoreReg(SP_REG, &success);
924    if (!success)
925      return false;
926    uint32_t registers = 0;
927    uint32_t Rt; // the source register
928    switch (encoding) {
929    case eEncodingT1:
930      registers = Bits32(opcode, 7, 0);
931      // The M bit represents LR.
932      if (Bit32(opcode, 8))
933        registers |= (1u << 14);
934      // if BitCount(registers) < 1 then UNPREDICTABLE;
935      if (BitCount(registers) < 1)
936        return false;
937      break;
938    case eEncodingT2:
939      // Ignore bits 15 & 13.
940      registers = Bits32(opcode, 15, 0) & ~0xa000;
941      // if BitCount(registers) < 2 then UNPREDICTABLE;
942      if (BitCount(registers) < 2)
943        return false;
944      break;
945    case eEncodingT3:
946      Rt = Bits32(opcode, 15, 12);
947      // if BadReg(t) then UNPREDICTABLE;
948      if (BadReg(Rt))
949        return false;
950      registers = (1u << Rt);
951      break;
952    case eEncodingA1:
953      registers = Bits32(opcode, 15, 0);
954      // Instead of return false, let's handle the following case as well,
955      // which amounts to pushing one reg onto the full descending stacks.
956      // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
957      break;
958    case eEncodingA2:
959      Rt = Bits32(opcode, 15, 12);
960      // if t == 13 then UNPREDICTABLE;
961      if (Rt == dwarf_sp)
962        return false;
963      registers = (1u << Rt);
964      break;
965    default:
966      return false;
967    }
968    addr_t sp_offset = addr_byte_size * BitCount(registers);
969    addr_t addr = sp - sp_offset;
970    uint32_t i;
971
972    EmulateInstruction::Context context;
973    context.type = EmulateInstruction::eContextPushRegisterOnStack;
974    std::optional<RegisterInfo> sp_reg =
975        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
976    for (i = 0; i < 15; ++i) {
977      if (BitIsSet(registers, i)) {
978        std::optional<RegisterInfo> reg_info =
979            GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
980        context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
981        uint32_t reg_value = ReadCoreReg(i, &success);
982        if (!success)
983          return false;
984        if (!MemAWrite(context, addr, reg_value, addr_byte_size))
985          return false;
986        addr += addr_byte_size;
987      }
988    }
989
990    if (BitIsSet(registers, 15)) {
991      std::optional<RegisterInfo> reg_info =
992          GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
993      context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
994      const uint32_t pc = ReadCoreReg(PC_REG, &success);
995      if (!success)
996        return false;
997      if (!MemAWrite(context, addr, pc, addr_byte_size))
998        return false;
999    }
1000
1001    context.type = EmulateInstruction::eContextAdjustStackPointer;
1002    context.SetImmediateSigned(-sp_offset);
1003
1004    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1005                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1006      return false;
1007  }
1008  return true;
1009}
1010
1011// Pop Multiple Registers loads multiple registers from the stack, loading from
1012// consecutive memory locations staring at the address in SP, and updates
1013// SP to point just above the loaded data.
1014bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1015                                       const ARMEncoding encoding) {
1016#if 0
1017    // ARM pseudo code...
1018    if (ConditionPassed())
1019    {
1020        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1021        address = SP;
1022        for i = 0 to 14
1023            if registers<i> == '1' then
1024                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1025        if registers<15> == '1' then
1026            if UnalignedAllowed then
1027                LoadWritePC(MemU[address,4]);
1028            else
1029                LoadWritePC(MemA[address,4]);
1030        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1031        if registers<13> == '1' then SP = bits(32) UNKNOWN;
1032    }
1033#endif
1034
1035  bool success = false;
1036
1037  if (ConditionPassed(opcode)) {
1038    const uint32_t addr_byte_size = GetAddressByteSize();
1039    const addr_t sp = ReadCoreReg(SP_REG, &success);
1040    if (!success)
1041      return false;
1042    uint32_t registers = 0;
1043    uint32_t Rt; // the destination register
1044    switch (encoding) {
1045    case eEncodingT1:
1046      registers = Bits32(opcode, 7, 0);
1047      // The P bit represents PC.
1048      if (Bit32(opcode, 8))
1049        registers |= (1u << 15);
1050      // if BitCount(registers) < 1 then UNPREDICTABLE;
1051      if (BitCount(registers) < 1)
1052        return false;
1053      break;
1054    case eEncodingT2:
1055      // Ignore bit 13.
1056      registers = Bits32(opcode, 15, 0) & ~0x2000;
1057      // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1058      // UNPREDICTABLE;
1059      if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1060        return false;
1061      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1062      // UNPREDICTABLE;
1063      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1064        return false;
1065      break;
1066    case eEncodingT3:
1067      Rt = Bits32(opcode, 15, 12);
1068      // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1069      // UNPREDICTABLE;
1070      if (Rt == 13)
1071        return false;
1072      if (Rt == 15 && InITBlock() && !LastInITBlock())
1073        return false;
1074      registers = (1u << Rt);
1075      break;
1076    case eEncodingA1:
1077      registers = Bits32(opcode, 15, 0);
1078      // Instead of return false, let's handle the following case as well,
1079      // which amounts to popping one reg from the full descending stacks.
1080      // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1081
1082      // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1083      if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1084        return false;
1085      break;
1086    case eEncodingA2:
1087      Rt = Bits32(opcode, 15, 12);
1088      // if t == 13 then UNPREDICTABLE;
1089      if (Rt == dwarf_sp)
1090        return false;
1091      registers = (1u << Rt);
1092      break;
1093    default:
1094      return false;
1095    }
1096    addr_t sp_offset = addr_byte_size * BitCount(registers);
1097    addr_t addr = sp;
1098    uint32_t i, data;
1099
1100    EmulateInstruction::Context context;
1101    context.type = EmulateInstruction::eContextPopRegisterOffStack;
1102
1103    std::optional<RegisterInfo> sp_reg =
1104        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1105
1106    for (i = 0; i < 15; ++i) {
1107      if (BitIsSet(registers, i)) {
1108        context.SetAddress(addr);
1109        data = MemARead(context, addr, 4, 0, &success);
1110        if (!success)
1111          return false;
1112        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1113                                   data))
1114          return false;
1115        addr += addr_byte_size;
1116      }
1117    }
1118
1119    if (BitIsSet(registers, 15)) {
1120      context.SetRegisterPlusOffset(*sp_reg, addr - sp);
1121      data = MemARead(context, addr, 4, 0, &success);
1122      if (!success)
1123        return false;
1124      // In ARMv5T and above, this is an interworking branch.
1125      if (!LoadWritePC(context, data))
1126        return false;
1127      // addr += addr_byte_size;
1128    }
1129
1130    context.type = EmulateInstruction::eContextAdjustStackPointer;
1131    context.SetImmediateSigned(sp_offset);
1132
1133    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1134                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1135      return false;
1136  }
1137  return true;
1138}
1139
1140// Set r7 or ip to point to saved value residing within the stack.
1141// ADD (SP plus immediate)
1142bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1143                                              const ARMEncoding encoding) {
1144#if 0
1145    // ARM pseudo code...
1146    if (ConditionPassed())
1147    {
1148        EncodingSpecificOperations();
1149        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1150        if d == 15 then
1151           ALUWritePC(result); // setflags is always FALSE here
1152        else
1153            R[d] = result;
1154            if setflags then
1155                APSR.N = result<31>;
1156                APSR.Z = IsZeroBit(result);
1157                APSR.C = carry;
1158                APSR.V = overflow;
1159    }
1160#endif
1161
1162  bool success = false;
1163
1164  if (ConditionPassed(opcode)) {
1165    const addr_t sp = ReadCoreReg(SP_REG, &success);
1166    if (!success)
1167      return false;
1168    uint32_t Rd; // the destination register
1169    uint32_t imm32;
1170    switch (encoding) {
1171    case eEncodingT1:
1172      Rd = 7;
1173      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1174      break;
1175    case eEncodingA1:
1176      Rd = Bits32(opcode, 15, 12);
1177      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1178      break;
1179    default:
1180      return false;
1181    }
1182    addr_t sp_offset = imm32;
1183    addr_t addr = sp + sp_offset; // a pointer to the stack area
1184
1185    EmulateInstruction::Context context;
1186    if (Rd == GetFramePointerRegisterNumber())
1187      context.type = eContextSetFramePointer;
1188    else
1189      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1190    std::optional<RegisterInfo> sp_reg =
1191        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1192    context.SetRegisterPlusOffset(*sp_reg, sp_offset);
1193
1194    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1195                               addr))
1196      return false;
1197  }
1198  return true;
1199}
1200
1201// Set r7 or ip to the current stack pointer.
1202// MOV (register)
1203bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1204                                           const ARMEncoding encoding) {
1205#if 0
1206    // ARM pseudo code...
1207    if (ConditionPassed())
1208    {
1209        EncodingSpecificOperations();
1210        result = R[m];
1211        if d == 15 then
1212            ALUWritePC(result); // setflags is always FALSE here
1213        else
1214            R[d] = result;
1215            if setflags then
1216                APSR.N = result<31>;
1217                APSR.Z = IsZeroBit(result);
1218                // APSR.C unchanged
1219                // APSR.V unchanged
1220    }
1221#endif
1222
1223  bool success = false;
1224
1225  if (ConditionPassed(opcode)) {
1226    const addr_t sp = ReadCoreReg(SP_REG, &success);
1227    if (!success)
1228      return false;
1229    uint32_t Rd; // the destination register
1230    switch (encoding) {
1231    case eEncodingT1:
1232      Rd = 7;
1233      break;
1234    case eEncodingA1:
1235      Rd = 12;
1236      break;
1237    default:
1238      return false;
1239    }
1240
1241    EmulateInstruction::Context context;
1242    if (Rd == GetFramePointerRegisterNumber())
1243      context.type = EmulateInstruction::eContextSetFramePointer;
1244    else
1245      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1246    std::optional<RegisterInfo> sp_reg =
1247        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1248    context.SetRegisterPlusOffset(*sp_reg, 0);
1249
1250    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1251      return false;
1252  }
1253  return true;
1254}
1255
1256// Move from high register (r8-r15) to low register (r0-r7).
1257// MOV (register)
1258bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1259                                              const ARMEncoding encoding) {
1260  return EmulateMOVRdRm(opcode, encoding);
1261}
1262
1263// Move from register to register.
1264// MOV (register)
1265bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1266                                           const ARMEncoding encoding) {
1267#if 0
1268    // ARM pseudo code...
1269    if (ConditionPassed())
1270    {
1271        EncodingSpecificOperations();
1272        result = R[m];
1273        if d == 15 then
1274            ALUWritePC(result); // setflags is always FALSE here
1275        else
1276            R[d] = result;
1277            if setflags then
1278                APSR.N = result<31>;
1279                APSR.Z = IsZeroBit(result);
1280                // APSR.C unchanged
1281                // APSR.V unchanged
1282    }
1283#endif
1284
1285  bool success = false;
1286
1287  if (ConditionPassed(opcode)) {
1288    uint32_t Rm; // the source register
1289    uint32_t Rd; // the destination register
1290    bool setflags;
1291    switch (encoding) {
1292    case eEncodingT1:
1293      Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1294      Rm = Bits32(opcode, 6, 3);
1295      setflags = false;
1296      if (Rd == 15 && InITBlock() && !LastInITBlock())
1297        return false;
1298      break;
1299    case eEncodingT2:
1300      Rd = Bits32(opcode, 2, 0);
1301      Rm = Bits32(opcode, 5, 3);
1302      setflags = true;
1303      if (InITBlock())
1304        return false;
1305      break;
1306    case eEncodingT3:
1307      Rd = Bits32(opcode, 11, 8);
1308      Rm = Bits32(opcode, 3, 0);
1309      setflags = BitIsSet(opcode, 20);
1310      // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1311      if (setflags && (BadReg(Rd) || BadReg(Rm)))
1312        return false;
1313      // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1314      // UNPREDICTABLE;
1315      if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1316        return false;
1317      break;
1318    case eEncodingA1:
1319      Rd = Bits32(opcode, 15, 12);
1320      Rm = Bits32(opcode, 3, 0);
1321      setflags = BitIsSet(opcode, 20);
1322
1323      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1324      // instructions;
1325      if (Rd == 15 && setflags)
1326        return EmulateSUBSPcLrEtc(opcode, encoding);
1327      break;
1328    default:
1329      return false;
1330    }
1331    uint32_t result = ReadCoreReg(Rm, &success);
1332    if (!success)
1333      return false;
1334
1335    // The context specifies that Rm is to be moved into Rd.
1336    EmulateInstruction::Context context;
1337    if (Rd == 13)
1338      context.type = EmulateInstruction::eContextAdjustStackPointer;
1339    else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1340      context.type = EmulateInstruction::eContextSetFramePointer;
1341    else
1342      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1343    std::optional<RegisterInfo> dwarf_reg =
1344        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
1345    context.SetRegisterPlusOffset(*dwarf_reg, 0);
1346
1347    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1348      return false;
1349  }
1350  return true;
1351}
1352
1353// Move (immediate) writes an immediate value to the destination register.  It
1354// can optionally update the condition flags based on the value.
1355// MOV (immediate)
1356bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1357                                            const ARMEncoding encoding) {
1358#if 0
1359    // ARM pseudo code...
1360    if (ConditionPassed())
1361    {
1362        EncodingSpecificOperations();
1363        result = imm32;
1364        if d == 15 then         // Can only occur for ARM encoding
1365            ALUWritePC(result); // setflags is always FALSE here
1366        else
1367            R[d] = result;
1368            if setflags then
1369                APSR.N = result<31>;
1370                APSR.Z = IsZeroBit(result);
1371                APSR.C = carry;
1372                // APSR.V unchanged
1373    }
1374#endif
1375
1376  if (ConditionPassed(opcode)) {
1377    uint32_t Rd;    // the destination register
1378    uint32_t imm32; // the immediate value to be written to Rd
1379    uint32_t carry =
1380        0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1381           // for setflags == false, this value is a don't care initialized to
1382           // 0 to silence the static analyzer
1383    bool setflags;
1384    switch (encoding) {
1385    case eEncodingT1:
1386      Rd = Bits32(opcode, 10, 8);
1387      setflags = !InITBlock();
1388      imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1389      carry = APSR_C;
1390
1391      break;
1392
1393    case eEncodingT2:
1394      Rd = Bits32(opcode, 11, 8);
1395      setflags = BitIsSet(opcode, 20);
1396      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1397      if (BadReg(Rd))
1398        return false;
1399
1400      break;
1401
1402    case eEncodingT3: {
1403      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1404      // 32);
1405      Rd = Bits32(opcode, 11, 8);
1406      setflags = false;
1407      uint32_t imm4 = Bits32(opcode, 19, 16);
1408      uint32_t imm3 = Bits32(opcode, 14, 12);
1409      uint32_t i = Bit32(opcode, 26);
1410      uint32_t imm8 = Bits32(opcode, 7, 0);
1411      imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1412
1413      // if BadReg(d) then UNPREDICTABLE;
1414      if (BadReg(Rd))
1415        return false;
1416    } break;
1417
1418    case eEncodingA1:
1419      // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1420      // ARMExpandImm_C(imm12, APSR.C);
1421      Rd = Bits32(opcode, 15, 12);
1422      setflags = BitIsSet(opcode, 20);
1423      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1424
1425      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1426      // instructions;
1427      if ((Rd == 15) && setflags)
1428        return EmulateSUBSPcLrEtc(opcode, encoding);
1429
1430      break;
1431
1432    case eEncodingA2: {
1433      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1434      Rd = Bits32(opcode, 15, 12);
1435      setflags = false;
1436      uint32_t imm4 = Bits32(opcode, 19, 16);
1437      uint32_t imm12 = Bits32(opcode, 11, 0);
1438      imm32 = (imm4 << 12) | imm12;
1439
1440      // if d == 15 then UNPREDICTABLE;
1441      if (Rd == 15)
1442        return false;
1443    } break;
1444
1445    default:
1446      return false;
1447    }
1448    uint32_t result = imm32;
1449
1450    // The context specifies that an immediate is to be moved into Rd.
1451    EmulateInstruction::Context context;
1452    context.type = EmulateInstruction::eContextImmediate;
1453    context.SetNoArgs();
1454
1455    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1456      return false;
1457  }
1458  return true;
1459}
1460
1461// MUL multiplies two register values.  The least significant 32 bits of the
1462// result are written to the destination
1463// register.  These 32 bits do not depend on whether the source register values
1464// are considered to be signed values or unsigned values.
1465//
1466// Optionally, it can update the condition flags based on the result.  In the
1467// Thumb instruction set, this option is limited to only a few forms of the
1468// instruction.
1469bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1470                                       const ARMEncoding encoding) {
1471#if 0
1472    if ConditionPassed() then
1473        EncodingSpecificOperations();
1474        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1475        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1476        result = operand1 * operand2;
1477        R[d] = result<31:0>;
1478        if setflags then
1479            APSR.N = result<31>;
1480            APSR.Z = IsZeroBit(result);
1481            if ArchVersion() == 4 then
1482                APSR.C = bit UNKNOWN;
1483            // else APSR.C unchanged
1484            // APSR.V always unchanged
1485#endif
1486
1487  if (ConditionPassed(opcode)) {
1488    uint32_t d;
1489    uint32_t n;
1490    uint32_t m;
1491    bool setflags;
1492
1493    // EncodingSpecificOperations();
1494    switch (encoding) {
1495    case eEncodingT1:
1496      // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1497      d = Bits32(opcode, 2, 0);
1498      n = Bits32(opcode, 5, 3);
1499      m = Bits32(opcode, 2, 0);
1500      setflags = !InITBlock();
1501
1502      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1503      if ((ArchVersion() < ARMv6) && (d == n))
1504        return false;
1505
1506      break;
1507
1508    case eEncodingT2:
1509      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1510      d = Bits32(opcode, 11, 8);
1511      n = Bits32(opcode, 19, 16);
1512      m = Bits32(opcode, 3, 0);
1513      setflags = false;
1514
1515      // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1516      if (BadReg(d) || BadReg(n) || BadReg(m))
1517        return false;
1518
1519      break;
1520
1521    case eEncodingA1:
1522      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1523      d = Bits32(opcode, 19, 16);
1524      n = Bits32(opcode, 3, 0);
1525      m = Bits32(opcode, 11, 8);
1526      setflags = BitIsSet(opcode, 20);
1527
1528      // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1529      if ((d == 15) || (n == 15) || (m == 15))
1530        return false;
1531
1532      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1533      if ((ArchVersion() < ARMv6) && (d == n))
1534        return false;
1535
1536      break;
1537
1538    default:
1539      return false;
1540    }
1541
1542    bool success = false;
1543
1544    // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1545    // results
1546    uint64_t operand1 =
1547        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1548    if (!success)
1549      return false;
1550
1551    // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1552    // results
1553    uint64_t operand2 =
1554        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1555    if (!success)
1556      return false;
1557
1558    // result = operand1 * operand2;
1559    uint64_t result = operand1 * operand2;
1560
1561    // R[d] = result<31:0>;
1562    std::optional<RegisterInfo> op1_reg =
1563        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
1564    std::optional<RegisterInfo> op2_reg =
1565        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
1566
1567    EmulateInstruction::Context context;
1568    context.type = eContextArithmetic;
1569    context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
1570
1571    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1572                               (0x0000ffff & result)))
1573      return false;
1574
1575    // if setflags then
1576    if (setflags) {
1577      // APSR.N = result<31>;
1578      // APSR.Z = IsZeroBit(result);
1579      m_new_inst_cpsr = m_opcode_cpsr;
1580      SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1581      SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1582      if (m_new_inst_cpsr != m_opcode_cpsr) {
1583        if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1584                                   LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1585          return false;
1586      }
1587
1588      // if ArchVersion() == 4 then
1589      // APSR.C = bit UNKNOWN;
1590    }
1591  }
1592  return true;
1593}
1594
1595// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1596// the destination register. It can optionally update the condition flags based
1597// on the value.
1598bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1599                                          const ARMEncoding encoding) {
1600#if 0
1601    // ARM pseudo code...
1602    if (ConditionPassed())
1603    {
1604        EncodingSpecificOperations();
1605        result = NOT(imm32);
1606        if d == 15 then         // Can only occur for ARM encoding
1607            ALUWritePC(result); // setflags is always FALSE here
1608        else
1609            R[d] = result;
1610            if setflags then
1611                APSR.N = result<31>;
1612                APSR.Z = IsZeroBit(result);
1613                APSR.C = carry;
1614                // APSR.V unchanged
1615    }
1616#endif
1617
1618  if (ConditionPassed(opcode)) {
1619    uint32_t Rd;    // the destination register
1620    uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1621    uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1622    bool setflags;
1623    switch (encoding) {
1624    case eEncodingT1:
1625      Rd = Bits32(opcode, 11, 8);
1626      setflags = BitIsSet(opcode, 20);
1627      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1628      break;
1629    case eEncodingA1:
1630      Rd = Bits32(opcode, 15, 12);
1631      setflags = BitIsSet(opcode, 20);
1632      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1633
1634      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1635      // instructions;
1636      if (Rd == 15 && setflags)
1637        return EmulateSUBSPcLrEtc(opcode, encoding);
1638      break;
1639    default:
1640      return false;
1641    }
1642    uint32_t result = ~imm32;
1643
1644    // The context specifies that an immediate is to be moved into Rd.
1645    EmulateInstruction::Context context;
1646    context.type = EmulateInstruction::eContextImmediate;
1647    context.SetNoArgs();
1648
1649    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1650      return false;
1651  }
1652  return true;
1653}
1654
1655// Bitwise NOT (register) writes the bitwise inverse of a register value to the
1656// destination register. It can optionally update the condition flags based on
1657// the result.
1658bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1659                                          const ARMEncoding encoding) {
1660#if 0
1661    // ARM pseudo code...
1662    if (ConditionPassed())
1663    {
1664        EncodingSpecificOperations();
1665        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1666        result = NOT(shifted);
1667        if d == 15 then         // Can only occur for ARM encoding
1668            ALUWritePC(result); // setflags is always FALSE here
1669        else
1670            R[d] = result;
1671            if setflags then
1672                APSR.N = result<31>;
1673                APSR.Z = IsZeroBit(result);
1674                APSR.C = carry;
1675                // APSR.V unchanged
1676    }
1677#endif
1678
1679  if (ConditionPassed(opcode)) {
1680    uint32_t Rm; // the source register
1681    uint32_t Rd; // the destination register
1682    ARM_ShifterType shift_t;
1683    uint32_t shift_n; // the shift applied to the value read from Rm
1684    bool setflags;
1685    uint32_t carry; // the carry bit after the shift operation
1686    switch (encoding) {
1687    case eEncodingT1:
1688      Rd = Bits32(opcode, 2, 0);
1689      Rm = Bits32(opcode, 5, 3);
1690      setflags = !InITBlock();
1691      shift_t = SRType_LSL;
1692      shift_n = 0;
1693      if (InITBlock())
1694        return false;
1695      break;
1696    case eEncodingT2:
1697      Rd = Bits32(opcode, 11, 8);
1698      Rm = Bits32(opcode, 3, 0);
1699      setflags = BitIsSet(opcode, 20);
1700      shift_n = DecodeImmShiftThumb(opcode, shift_t);
1701      // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1702      if (BadReg(Rd) || BadReg(Rm))
1703        return false;
1704      break;
1705    case eEncodingA1:
1706      Rd = Bits32(opcode, 15, 12);
1707      Rm = Bits32(opcode, 3, 0);
1708      setflags = BitIsSet(opcode, 20);
1709      shift_n = DecodeImmShiftARM(opcode, shift_t);
1710      break;
1711    default:
1712      return false;
1713    }
1714    bool success = false;
1715    uint32_t value = ReadCoreReg(Rm, &success);
1716    if (!success)
1717      return false;
1718
1719    uint32_t shifted =
1720        Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1721    if (!success)
1722      return false;
1723    uint32_t result = ~shifted;
1724
1725    // The context specifies that an immediate is to be moved into Rd.
1726    EmulateInstruction::Context context;
1727    context.type = EmulateInstruction::eContextImmediate;
1728    context.SetNoArgs();
1729
1730    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1731      return false;
1732  }
1733  return true;
1734}
1735
1736// PC relative immediate load into register, possibly followed by ADD (SP plus
1737// register).
1738// LDR (literal)
1739bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1740                                                   const ARMEncoding encoding) {
1741#if 0
1742    // ARM pseudo code...
1743    if (ConditionPassed())
1744    {
1745        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1746        base = Align(PC,4);
1747        address = if add then (base + imm32) else (base - imm32);
1748        data = MemU[address,4];
1749        if t == 15 then
1750            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1751        elsif UnalignedSupport() || address<1:0> = '00' then
1752            R[t] = data;
1753        else // Can only apply before ARMv7
1754            if CurrentInstrSet() == InstrSet_ARM then
1755                R[t] = ROR(data, 8*UInt(address<1:0>));
1756            else
1757                R[t] = bits(32) UNKNOWN;
1758    }
1759#endif
1760
1761  if (ConditionPassed(opcode)) {
1762    bool success = false;
1763    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1764    if (!success)
1765      return false;
1766
1767    // PC relative immediate load context
1768    EmulateInstruction::Context context;
1769    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1770    std::optional<RegisterInfo> pc_reg =
1771        GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
1772    context.SetRegisterPlusOffset(*pc_reg, 0);
1773
1774    uint32_t Rt;    // the destination register
1775    uint32_t imm32; // immediate offset from the PC
1776    bool add;       // +imm32 or -imm32?
1777    addr_t base;    // the base address
1778    addr_t address; // the PC relative address
1779    uint32_t data;  // the literal data value from the PC relative load
1780    switch (encoding) {
1781    case eEncodingT1:
1782      Rt = Bits32(opcode, 10, 8);
1783      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1784      add = true;
1785      break;
1786    case eEncodingT2:
1787      Rt = Bits32(opcode, 15, 12);
1788      imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1789      add = BitIsSet(opcode, 23);
1790      if (Rt == 15 && InITBlock() && !LastInITBlock())
1791        return false;
1792      break;
1793    default:
1794      return false;
1795    }
1796
1797    base = Align(pc, 4);
1798    if (add)
1799      address = base + imm32;
1800    else
1801      address = base - imm32;
1802
1803    context.SetRegisterPlusOffset(*pc_reg, address - base);
1804    data = MemURead(context, address, 4, 0, &success);
1805    if (!success)
1806      return false;
1807
1808    if (Rt == 15) {
1809      if (Bits32(address, 1, 0) == 0) {
1810        // In ARMv5T and above, this is an interworking branch.
1811        if (!LoadWritePC(context, data))
1812          return false;
1813      } else
1814        return false;
1815    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1816      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1817                                 data))
1818        return false;
1819    } else // We don't handle ARM for now.
1820      return false;
1821  }
1822  return true;
1823}
1824
1825// An add operation to adjust the SP.
1826// ADD (SP plus immediate)
1827bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1828                                            const ARMEncoding encoding) {
1829#if 0
1830    // ARM pseudo code...
1831    if (ConditionPassed())
1832    {
1833        EncodingSpecificOperations();
1834        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1835        if d == 15 then // Can only occur for ARM encoding
1836            ALUWritePC(result); // setflags is always FALSE here
1837        else
1838            R[d] = result;
1839            if setflags then
1840                APSR.N = result<31>;
1841                APSR.Z = IsZeroBit(result);
1842                APSR.C = carry;
1843                APSR.V = overflow;
1844    }
1845#endif
1846
1847  bool success = false;
1848
1849  if (ConditionPassed(opcode)) {
1850    const addr_t sp = ReadCoreReg(SP_REG, &success);
1851    if (!success)
1852      return false;
1853    uint32_t imm32; // the immediate operand
1854    uint32_t d;
1855    bool setflags;
1856    switch (encoding) {
1857    case eEncodingT1:
1858      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1859      d = Bits32(opcode, 10, 8);
1860      imm32 = (Bits32(opcode, 7, 0) << 2);
1861      setflags = false;
1862      break;
1863
1864    case eEncodingT2:
1865      // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1866      d = 13;
1867      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1868      setflags = false;
1869      break;
1870
1871    case eEncodingT3:
1872      // d = UInt(Rd); setflags = (S == "1"); imm32 =
1873      // ThumbExpandImm(i:imm3:imm8);
1874      d = Bits32(opcode, 11, 8);
1875      imm32 = ThumbExpandImm(opcode);
1876      setflags = Bit32(opcode, 20);
1877
1878      // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1879      if (d == 15 && setflags == 1)
1880        return false; // CMN (immediate) not yet supported
1881
1882      // if d == 15 && S == "0" then UNPREDICTABLE;
1883      if (d == 15 && setflags == 0)
1884        return false;
1885      break;
1886
1887    case eEncodingT4: {
1888      // if Rn == '1111' then SEE ADR;
1889      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1890      d = Bits32(opcode, 11, 8);
1891      setflags = false;
1892      uint32_t i = Bit32(opcode, 26);
1893      uint32_t imm3 = Bits32(opcode, 14, 12);
1894      uint32_t imm8 = Bits32(opcode, 7, 0);
1895      imm32 = (i << 11) | (imm3 << 8) | imm8;
1896
1897      // if d == 15 then UNPREDICTABLE;
1898      if (d == 15)
1899        return false;
1900    } break;
1901
1902    default:
1903      return false;
1904    }
1905    // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1906    AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1907
1908    EmulateInstruction::Context context;
1909    if (d == 13)
1910      context.type = EmulateInstruction::eContextAdjustStackPointer;
1911    else
1912      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1913
1914    std::optional<RegisterInfo> sp_reg =
1915        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1916    context.SetRegisterPlusOffset(*sp_reg, res.result - sp);
1917
1918    if (d == 15) {
1919      if (!ALUWritePC(context, res.result))
1920        return false;
1921    } else {
1922      // R[d] = result;
1923      // if setflags then
1924      //     APSR.N = result<31>;
1925      //     APSR.Z = IsZeroBit(result);
1926      //     APSR.C = carry;
1927      //     APSR.V = overflow;
1928      if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1929                                     res.carry_out, res.overflow))
1930        return false;
1931    }
1932  }
1933  return true;
1934}
1935
1936// An add operation to adjust the SP.
1937// ADD (SP plus register)
1938bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1939                                           const ARMEncoding encoding) {
1940#if 0
1941    // ARM pseudo code...
1942    if (ConditionPassed())
1943    {
1944        EncodingSpecificOperations();
1945        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1946        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1947        if d == 15 then
1948            ALUWritePC(result); // setflags is always FALSE here
1949        else
1950            R[d] = result;
1951            if setflags then
1952                APSR.N = result<31>;
1953                APSR.Z = IsZeroBit(result);
1954                APSR.C = carry;
1955                APSR.V = overflow;
1956    }
1957#endif
1958
1959  bool success = false;
1960
1961  if (ConditionPassed(opcode)) {
1962    const addr_t sp = ReadCoreReg(SP_REG, &success);
1963    if (!success)
1964      return false;
1965    uint32_t Rm; // the second operand
1966    switch (encoding) {
1967    case eEncodingT2:
1968      Rm = Bits32(opcode, 6, 3);
1969      break;
1970    default:
1971      return false;
1972    }
1973    int32_t reg_value = ReadCoreReg(Rm, &success);
1974    if (!success)
1975      return false;
1976
1977    addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1978
1979    EmulateInstruction::Context context;
1980    context.type = eContextArithmetic;
1981    std::optional<RegisterInfo> sp_reg =
1982        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1983    std::optional<RegisterInfo> other_reg =
1984        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
1985    context.SetRegisterRegisterOperands(*sp_reg, *other_reg);
1986
1987    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1988                               LLDB_REGNUM_GENERIC_SP, addr))
1989      return false;
1990  }
1991  return true;
1992}
1993
1994// Branch with Link and Exchange Instruction Sets (immediate) calls a
1995// subroutine at a PC-relative address, and changes instruction set from ARM to
1996// Thumb, or from Thumb to ARM.
1997// BLX (immediate)
1998bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
1999                                                const ARMEncoding encoding) {
2000#if 0
2001    // ARM pseudo code...
2002    if (ConditionPassed())
2003    {
2004        EncodingSpecificOperations();
2005        if CurrentInstrSet() == InstrSet_ARM then
2006            LR = PC - 4;
2007        else
2008            LR = PC<31:1> : '1';
2009        if targetInstrSet == InstrSet_ARM then
2010            targetAddress = Align(PC,4) + imm32;
2011        else
2012            targetAddress = PC + imm32;
2013        SelectInstrSet(targetInstrSet);
2014        BranchWritePC(targetAddress);
2015    }
2016#endif
2017
2018  bool success = true;
2019
2020  if (ConditionPassed(opcode)) {
2021    EmulateInstruction::Context context;
2022    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2023    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2024    if (!success)
2025      return false;
2026    addr_t lr;     // next instruction address
2027    addr_t target; // target address
2028    int32_t imm32; // PC-relative offset
2029    switch (encoding) {
2030    case eEncodingT1: {
2031      lr = pc | 1u; // return address
2032      uint32_t S = Bit32(opcode, 26);
2033      uint32_t imm10 = Bits32(opcode, 25, 16);
2034      uint32_t J1 = Bit32(opcode, 13);
2035      uint32_t J2 = Bit32(opcode, 11);
2036      uint32_t imm11 = Bits32(opcode, 10, 0);
2037      uint32_t I1 = !(J1 ^ S);
2038      uint32_t I2 = !(J2 ^ S);
2039      uint32_t imm25 =
2040          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2041      imm32 = llvm::SignExtend32<25>(imm25);
2042      target = pc + imm32;
2043      SelectInstrSet(eModeThumb);
2044      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2045      if (InITBlock() && !LastInITBlock())
2046        return false;
2047      break;
2048    }
2049    case eEncodingT2: {
2050      lr = pc | 1u; // return address
2051      uint32_t S = Bit32(opcode, 26);
2052      uint32_t imm10H = Bits32(opcode, 25, 16);
2053      uint32_t J1 = Bit32(opcode, 13);
2054      uint32_t J2 = Bit32(opcode, 11);
2055      uint32_t imm10L = Bits32(opcode, 10, 1);
2056      uint32_t I1 = !(J1 ^ S);
2057      uint32_t I2 = !(J2 ^ S);
2058      uint32_t imm25 =
2059          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2060      imm32 = llvm::SignExtend32<25>(imm25);
2061      target = Align(pc, 4) + imm32;
2062      SelectInstrSet(eModeARM);
2063      context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2064      if (InITBlock() && !LastInITBlock())
2065        return false;
2066      break;
2067    }
2068    case eEncodingA1:
2069      lr = pc - 4; // return address
2070      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2071      target = Align(pc, 4) + imm32;
2072      SelectInstrSet(eModeARM);
2073      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2074      break;
2075    case eEncodingA2:
2076      lr = pc - 4; // return address
2077      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2078                                     Bits32(opcode, 24, 24) << 1);
2079      target = pc + imm32;
2080      SelectInstrSet(eModeThumb);
2081      context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2082      break;
2083    default:
2084      return false;
2085    }
2086    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2087                               LLDB_REGNUM_GENERIC_RA, lr))
2088      return false;
2089    if (!BranchWritePC(context, target))
2090      return false;
2091    if (m_opcode_cpsr != m_new_inst_cpsr)
2092      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2093                                 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2094        return false;
2095  }
2096  return true;
2097}
2098
2099// Branch with Link and Exchange (register) calls a subroutine at an address
2100// and instruction set specified by a register.
2101// BLX (register)
2102bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2103                                         const ARMEncoding encoding) {
2104#if 0
2105    // ARM pseudo code...
2106    if (ConditionPassed())
2107    {
2108        EncodingSpecificOperations();
2109        target = R[m];
2110        if CurrentInstrSet() == InstrSet_ARM then
2111            next_instr_addr = PC - 4;
2112            LR = next_instr_addr;
2113        else
2114            next_instr_addr = PC - 2;
2115            LR = next_instr_addr<31:1> : '1';
2116        BXWritePC(target);
2117    }
2118#endif
2119
2120  bool success = false;
2121
2122  if (ConditionPassed(opcode)) {
2123    EmulateInstruction::Context context;
2124    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2125    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2126    addr_t lr; // next instruction address
2127    if (!success)
2128      return false;
2129    uint32_t Rm; // the register with the target address
2130    switch (encoding) {
2131    case eEncodingT1:
2132      lr = (pc - 2) | 1u; // return address
2133      Rm = Bits32(opcode, 6, 3);
2134      // if m == 15 then UNPREDICTABLE;
2135      if (Rm == 15)
2136        return false;
2137      if (InITBlock() && !LastInITBlock())
2138        return false;
2139      break;
2140    case eEncodingA1:
2141      lr = pc - 4; // return address
2142      Rm = Bits32(opcode, 3, 0);
2143      // if m == 15 then UNPREDICTABLE;
2144      if (Rm == 15)
2145        return false;
2146      break;
2147    default:
2148      return false;
2149    }
2150    addr_t target = ReadCoreReg(Rm, &success);
2151    if (!success)
2152      return false;
2153    std::optional<RegisterInfo> dwarf_reg =
2154        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2155    context.SetRegister(*dwarf_reg);
2156    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2157                               LLDB_REGNUM_GENERIC_RA, lr))
2158      return false;
2159    if (!BXWritePC(context, target))
2160      return false;
2161  }
2162  return true;
2163}
2164
2165// Branch and Exchange causes a branch to an address and instruction set
2166// specified by a register.
2167bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2168                                        const ARMEncoding encoding) {
2169#if 0
2170    // ARM pseudo code...
2171    if (ConditionPassed())
2172    {
2173        EncodingSpecificOperations();
2174        BXWritePC(R[m]);
2175    }
2176#endif
2177
2178  if (ConditionPassed(opcode)) {
2179    EmulateInstruction::Context context;
2180    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2181    uint32_t Rm; // the register with the target address
2182    switch (encoding) {
2183    case eEncodingT1:
2184      Rm = Bits32(opcode, 6, 3);
2185      if (InITBlock() && !LastInITBlock())
2186        return false;
2187      break;
2188    case eEncodingA1:
2189      Rm = Bits32(opcode, 3, 0);
2190      break;
2191    default:
2192      return false;
2193    }
2194    bool success = false;
2195    addr_t target = ReadCoreReg(Rm, &success);
2196    if (!success)
2197      return false;
2198
2199    std::optional<RegisterInfo> dwarf_reg =
2200        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2201    context.SetRegister(*dwarf_reg);
2202    if (!BXWritePC(context, target))
2203      return false;
2204  }
2205  return true;
2206}
2207
2208// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2209// attempt fails, it branches to an address and instruction set specified by a
2210// register as though it were a BX instruction.
2211//
2212// TODO: Emulate Jazelle architecture?
2213//       We currently assume that switching to Jazelle state fails, thus
2214//       treating BXJ as a BX operation.
2215bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2216                                         const ARMEncoding encoding) {
2217#if 0
2218    // ARM pseudo code...
2219    if (ConditionPassed())
2220    {
2221        EncodingSpecificOperations();
2222        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2223            BXWritePC(R[m]);
2224        else
2225            if JazelleAcceptsExecution() then
2226                SwitchToJazelleExecution();
2227            else
2228                SUBARCHITECTURE_DEFINED handler call;
2229    }
2230#endif
2231
2232  if (ConditionPassed(opcode)) {
2233    EmulateInstruction::Context context;
2234    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2235    uint32_t Rm; // the register with the target address
2236    switch (encoding) {
2237    case eEncodingT1:
2238      Rm = Bits32(opcode, 19, 16);
2239      if (BadReg(Rm))
2240        return false;
2241      if (InITBlock() && !LastInITBlock())
2242        return false;
2243      break;
2244    case eEncodingA1:
2245      Rm = Bits32(opcode, 3, 0);
2246      if (Rm == 15)
2247        return false;
2248      break;
2249    default:
2250      return false;
2251    }
2252    bool success = false;
2253    addr_t target = ReadCoreReg(Rm, &success);
2254    if (!success)
2255      return false;
2256
2257    std::optional<RegisterInfo> dwarf_reg =
2258        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2259    context.SetRegister(*dwarf_reg);
2260    if (!BXWritePC(context, target))
2261      return false;
2262  }
2263  return true;
2264}
2265
2266// Set r7 to point to some ip offset.
2267// SUB (immediate)
2268bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2269                                              const ARMEncoding encoding) {
2270#if 0
2271    // ARM pseudo code...
2272    if (ConditionPassed())
2273    {
2274        EncodingSpecificOperations();
2275        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2276        if d == 15 then // Can only occur for ARM encoding
2277           ALUWritePC(result); // setflags is always FALSE here
2278        else
2279            R[d] = result;
2280            if setflags then
2281                APSR.N = result<31>;
2282                APSR.Z = IsZeroBit(result);
2283                APSR.C = carry;
2284                APSR.V = overflow;
2285    }
2286#endif
2287
2288  if (ConditionPassed(opcode)) {
2289    bool success = false;
2290    const addr_t ip = ReadCoreReg(12, &success);
2291    if (!success)
2292      return false;
2293    uint32_t imm32;
2294    switch (encoding) {
2295    case eEncodingA1:
2296      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2297      break;
2298    default:
2299      return false;
2300    }
2301    addr_t ip_offset = imm32;
2302    addr_t addr = ip - ip_offset; // the adjusted ip value
2303
2304    EmulateInstruction::Context context;
2305    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2306    std::optional<RegisterInfo> dwarf_reg =
2307        GetRegisterInfo(eRegisterKindDWARF, dwarf_r12);
2308    context.SetRegisterPlusOffset(*dwarf_reg, -ip_offset);
2309
2310    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2311      return false;
2312  }
2313  return true;
2314}
2315
2316// Set ip to point to some stack offset.
2317// SUB (SP minus immediate)
2318bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2319                                              const ARMEncoding encoding) {
2320#if 0
2321    // ARM pseudo code...
2322    if (ConditionPassed())
2323    {
2324        EncodingSpecificOperations();
2325        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2326        if d == 15 then // Can only occur for ARM encoding
2327           ALUWritePC(result); // setflags is always FALSE here
2328        else
2329            R[d] = result;
2330            if setflags then
2331                APSR.N = result<31>;
2332                APSR.Z = IsZeroBit(result);
2333                APSR.C = carry;
2334                APSR.V = overflow;
2335    }
2336#endif
2337
2338  if (ConditionPassed(opcode)) {
2339    bool success = false;
2340    const addr_t sp = ReadCoreReg(SP_REG, &success);
2341    if (!success)
2342      return false;
2343    uint32_t imm32;
2344    switch (encoding) {
2345    case eEncodingA1:
2346      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2347      break;
2348    default:
2349      return false;
2350    }
2351    addr_t sp_offset = imm32;
2352    addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2353
2354    EmulateInstruction::Context context;
2355    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2356    std::optional<RegisterInfo> dwarf_reg =
2357        GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
2358    context.SetRegisterPlusOffset(*dwarf_reg, -sp_offset);
2359
2360    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2361      return false;
2362  }
2363  return true;
2364}
2365
2366// This instruction subtracts an immediate value from the SP value, and writes
2367// the result to the destination register.
2368//
2369// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2370// storage.
2371bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2372                                            const ARMEncoding encoding) {
2373#if 0
2374    // ARM pseudo code...
2375    if (ConditionPassed())
2376    {
2377        EncodingSpecificOperations();
2378        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2379        if d == 15 then        // Can only occur for ARM encoding
2380           ALUWritePC(result); // setflags is always FALSE here
2381        else
2382            R[d] = result;
2383            if setflags then
2384                APSR.N = result<31>;
2385                APSR.Z = IsZeroBit(result);
2386                APSR.C = carry;
2387                APSR.V = overflow;
2388    }
2389#endif
2390
2391  bool success = false;
2392  if (ConditionPassed(opcode)) {
2393    const addr_t sp = ReadCoreReg(SP_REG, &success);
2394    if (!success)
2395      return false;
2396
2397    uint32_t Rd;
2398    bool setflags;
2399    uint32_t imm32;
2400    switch (encoding) {
2401    case eEncodingT1:
2402      Rd = 13;
2403      setflags = false;
2404      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2405      break;
2406    case eEncodingT2:
2407      Rd = Bits32(opcode, 11, 8);
2408      setflags = BitIsSet(opcode, 20);
2409      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2410      if (Rd == 15 && setflags)
2411        return EmulateCMPImm(opcode, eEncodingT2);
2412      if (Rd == 15 && !setflags)
2413        return false;
2414      break;
2415    case eEncodingT3:
2416      Rd = Bits32(opcode, 11, 8);
2417      setflags = false;
2418      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2419      if (Rd == 15)
2420        return false;
2421      break;
2422    case eEncodingA1:
2423      Rd = Bits32(opcode, 15, 12);
2424      setflags = BitIsSet(opcode, 20);
2425      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2426
2427      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2428      // instructions;
2429      if (Rd == 15 && setflags)
2430        return EmulateSUBSPcLrEtc(opcode, encoding);
2431      break;
2432    default:
2433      return false;
2434    }
2435    AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2436
2437    EmulateInstruction::Context context;
2438    if (Rd == 13) {
2439      uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2440                              // to negate it, or the wrong
2441      // value gets passed down to context.SetImmediateSigned.
2442      context.type = EmulateInstruction::eContextAdjustStackPointer;
2443      context.SetImmediateSigned(-imm64); // the stack pointer offset
2444    } else {
2445      context.type = EmulateInstruction::eContextImmediate;
2446      context.SetNoArgs();
2447    }
2448
2449    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2450                                   res.carry_out, res.overflow))
2451      return false;
2452  }
2453  return true;
2454}
2455
2456// A store operation to the stack that also updates the SP.
2457bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2458                                           const ARMEncoding encoding) {
2459#if 0
2460    // ARM pseudo code...
2461    if (ConditionPassed())
2462    {
2463        EncodingSpecificOperations();
2464        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2465        address = if index then offset_addr else R[n];
2466        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2467        if wback then R[n] = offset_addr;
2468    }
2469#endif
2470
2471  bool success = false;
2472  if (ConditionPassed(opcode)) {
2473    const uint32_t addr_byte_size = GetAddressByteSize();
2474    const addr_t sp = ReadCoreReg(SP_REG, &success);
2475    if (!success)
2476      return false;
2477    uint32_t Rt; // the source register
2478    uint32_t imm12;
2479    uint32_t
2480        Rn; // This function assumes Rn is the SP, but we should verify that.
2481
2482    bool index;
2483    bool add;
2484    bool wback;
2485    switch (encoding) {
2486    case eEncodingA1:
2487      Rt = Bits32(opcode, 15, 12);
2488      imm12 = Bits32(opcode, 11, 0);
2489      Rn = Bits32(opcode, 19, 16);
2490
2491      if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2492        return false;
2493
2494      index = BitIsSet(opcode, 24);
2495      add = BitIsSet(opcode, 23);
2496      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2497
2498      if (wback && ((Rn == 15) || (Rn == Rt)))
2499        return false;
2500      break;
2501    default:
2502      return false;
2503    }
2504    addr_t offset_addr;
2505    if (add)
2506      offset_addr = sp + imm12;
2507    else
2508      offset_addr = sp - imm12;
2509
2510    addr_t addr;
2511    if (index)
2512      addr = offset_addr;
2513    else
2514      addr = sp;
2515
2516    EmulateInstruction::Context context;
2517    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2518    std::optional<RegisterInfo> sp_reg =
2519        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
2520    std::optional<RegisterInfo> dwarf_reg =
2521        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt);
2522
2523    context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2524    if (Rt != 15) {
2525      uint32_t reg_value = ReadCoreReg(Rt, &success);
2526      if (!success)
2527        return false;
2528      if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2529        return false;
2530    } else {
2531      const uint32_t pc = ReadCoreReg(PC_REG, &success);
2532      if (!success)
2533        return false;
2534      if (!MemUWrite(context, addr, pc, addr_byte_size))
2535        return false;
2536    }
2537
2538    if (wback) {
2539      context.type = EmulateInstruction::eContextAdjustStackPointer;
2540      context.SetImmediateSigned(addr - sp);
2541      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2542                                 LLDB_REGNUM_GENERIC_SP, offset_addr))
2543        return false;
2544    }
2545  }
2546  return true;
2547}
2548
2549// Vector Push stores multiple extension registers to the stack. It also
2550// updates SP to point to the start of the stored data.
2551bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2552                                         const ARMEncoding encoding) {
2553#if 0
2554    // ARM pseudo code...
2555    if (ConditionPassed())
2556    {
2557        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2558        address = SP - imm32;
2559        SP = SP - imm32;
2560        if single_regs then
2561            for r = 0 to regs-1
2562                MemA[address,4] = S[d+r]; address = address+4;
2563        else
2564            for r = 0 to regs-1
2565                // Store as two word-aligned words in the correct order for
2566                // current endianness.
2567                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2568                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2569                address = address+8;
2570    }
2571#endif
2572
2573  bool success = false;
2574  if (ConditionPassed(opcode)) {
2575    const uint32_t addr_byte_size = GetAddressByteSize();
2576    const addr_t sp = ReadCoreReg(SP_REG, &success);
2577    if (!success)
2578      return false;
2579    bool single_regs;
2580    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2581    uint32_t imm32; // stack offset
2582    uint32_t regs;  // number of registers
2583    switch (encoding) {
2584    case eEncodingT1:
2585    case eEncodingA1:
2586      single_regs = false;
2587      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2588      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2589      // If UInt(imm8) is odd, see "FSTMX".
2590      regs = Bits32(opcode, 7, 0) / 2;
2591      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2592      if (regs == 0 || regs > 16 || (d + regs) > 32)
2593        return false;
2594      break;
2595    case eEncodingT2:
2596    case eEncodingA2:
2597      single_regs = true;
2598      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2599      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2600      regs = Bits32(opcode, 7, 0);
2601      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2602      if (regs == 0 || regs > 16 || (d + regs) > 32)
2603        return false;
2604      break;
2605    default:
2606      return false;
2607    }
2608    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2609    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2610    addr_t sp_offset = imm32;
2611    addr_t addr = sp - sp_offset;
2612    uint32_t i;
2613
2614    EmulateInstruction::Context context;
2615    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2616
2617    std::optional<RegisterInfo> sp_reg =
2618        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
2619    for (i = 0; i < regs; ++i) {
2620      std::optional<RegisterInfo> dwarf_reg =
2621          GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2622      context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2623      // uint64_t to accommodate 64-bit registers.
2624      uint64_t reg_value = ReadRegisterUnsigned(*dwarf_reg, 0, &success);
2625      if (!success)
2626        return false;
2627      if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2628        return false;
2629      addr += reg_byte_size;
2630    }
2631
2632    context.type = EmulateInstruction::eContextAdjustStackPointer;
2633    context.SetImmediateSigned(-sp_offset);
2634
2635    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2636                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2637      return false;
2638  }
2639  return true;
2640}
2641
2642// Vector Pop loads multiple extension registers from the stack. It also
2643// updates SP to point just above the loaded data.
2644bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2645                                        const ARMEncoding encoding) {
2646#if 0
2647    // ARM pseudo code...
2648    if (ConditionPassed())
2649    {
2650        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2651        address = SP;
2652        SP = SP + imm32;
2653        if single_regs then
2654            for r = 0 to regs-1
2655                S[d+r] = MemA[address,4]; address = address+4;
2656        else
2657            for r = 0 to regs-1
2658                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2659                // Combine the word-aligned words in the correct order for
2660                // current endianness.
2661                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2662    }
2663#endif
2664
2665  bool success = false;
2666  if (ConditionPassed(opcode)) {
2667    const uint32_t addr_byte_size = GetAddressByteSize();
2668    const addr_t sp = ReadCoreReg(SP_REG, &success);
2669    if (!success)
2670      return false;
2671    bool single_regs;
2672    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2673    uint32_t imm32; // stack offset
2674    uint32_t regs;  // number of registers
2675    switch (encoding) {
2676    case eEncodingT1:
2677    case eEncodingA1:
2678      single_regs = false;
2679      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2680      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2681      // If UInt(imm8) is odd, see "FLDMX".
2682      regs = Bits32(opcode, 7, 0) / 2;
2683      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2684      if (regs == 0 || regs > 16 || (d + regs) > 32)
2685        return false;
2686      break;
2687    case eEncodingT2:
2688    case eEncodingA2:
2689      single_regs = true;
2690      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2691      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2692      regs = Bits32(opcode, 7, 0);
2693      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2694      if (regs == 0 || regs > 16 || (d + regs) > 32)
2695        return false;
2696      break;
2697    default:
2698      return false;
2699    }
2700    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2701    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2702    addr_t sp_offset = imm32;
2703    addr_t addr = sp;
2704    uint32_t i;
2705    uint64_t data; // uint64_t to accommodate 64-bit registers.
2706
2707    EmulateInstruction::Context context;
2708    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2709
2710    for (i = 0; i < regs; ++i) {
2711      std::optional<RegisterInfo> dwarf_reg =
2712          GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2713      context.SetAddress(addr);
2714      data = MemARead(context, addr, reg_byte_size, 0, &success);
2715      if (!success)
2716        return false;
2717      if (!WriteRegisterUnsigned(context, *dwarf_reg, data))
2718        return false;
2719      addr += reg_byte_size;
2720    }
2721
2722    context.type = EmulateInstruction::eContextAdjustStackPointer;
2723    context.SetImmediateSigned(sp_offset);
2724
2725    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2726                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2727      return false;
2728  }
2729  return true;
2730}
2731
2732// SVC (previously SWI)
2733bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2734                                       const ARMEncoding encoding) {
2735#if 0
2736    // ARM pseudo code...
2737    if (ConditionPassed())
2738    {
2739        EncodingSpecificOperations();
2740        CallSupervisor();
2741    }
2742#endif
2743
2744  bool success = false;
2745
2746  if (ConditionPassed(opcode)) {
2747    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2748    addr_t lr; // next instruction address
2749    if (!success)
2750      return false;
2751    uint32_t imm32; // the immediate constant
2752    uint32_t mode;  // ARM or Thumb mode
2753    switch (encoding) {
2754    case eEncodingT1:
2755      lr = (pc + 2) | 1u; // return address
2756      imm32 = Bits32(opcode, 7, 0);
2757      mode = eModeThumb;
2758      break;
2759    case eEncodingA1:
2760      lr = pc + 4; // return address
2761      imm32 = Bits32(opcode, 23, 0);
2762      mode = eModeARM;
2763      break;
2764    default:
2765      return false;
2766    }
2767
2768    EmulateInstruction::Context context;
2769    context.type = EmulateInstruction::eContextSupervisorCall;
2770    context.SetISAAndImmediate(mode, imm32);
2771    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2772                               LLDB_REGNUM_GENERIC_RA, lr))
2773      return false;
2774  }
2775  return true;
2776}
2777
2778// If Then makes up to four following instructions (the IT block) conditional.
2779bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2780                                      const ARMEncoding encoding) {
2781#if 0
2782    // ARM pseudo code...
2783    EncodingSpecificOperations();
2784    ITSTATE.IT<7:0> = firstcond:mask;
2785#endif
2786
2787  m_it_session.InitIT(Bits32(opcode, 7, 0));
2788  return true;
2789}
2790
2791bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2792                                       const ARMEncoding encoding) {
2793  // NOP, nothing to do...
2794  return true;
2795}
2796
2797// Branch causes a branch to a target address.
2798bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2799                                     const ARMEncoding encoding) {
2800#if 0
2801    // ARM pseudo code...
2802    if (ConditionPassed())
2803    {
2804        EncodingSpecificOperations();
2805        BranchWritePC(PC + imm32);
2806    }
2807#endif
2808
2809  bool success = false;
2810
2811  if (ConditionPassed(opcode)) {
2812    EmulateInstruction::Context context;
2813    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2814    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2815    if (!success)
2816      return false;
2817    addr_t target; // target address
2818    int32_t imm32; // PC-relative offset
2819    switch (encoding) {
2820    case eEncodingT1:
2821      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2822      imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2823      target = pc + imm32;
2824      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2825      break;
2826    case eEncodingT2:
2827      imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2828      target = pc + imm32;
2829      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2830      break;
2831    case eEncodingT3:
2832      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2833      {
2834        if (Bits32(opcode, 25, 23) == 7)
2835          return false; // See Branches and miscellaneous control on page
2836                        // A6-235.
2837
2838        uint32_t S = Bit32(opcode, 26);
2839        uint32_t imm6 = Bits32(opcode, 21, 16);
2840        uint32_t J1 = Bit32(opcode, 13);
2841        uint32_t J2 = Bit32(opcode, 11);
2842        uint32_t imm11 = Bits32(opcode, 10, 0);
2843        uint32_t imm21 =
2844            (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2845        imm32 = llvm::SignExtend32<21>(imm21);
2846        target = pc + imm32;
2847        context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2848        break;
2849      }
2850    case eEncodingT4: {
2851      uint32_t S = Bit32(opcode, 26);
2852      uint32_t imm10 = Bits32(opcode, 25, 16);
2853      uint32_t J1 = Bit32(opcode, 13);
2854      uint32_t J2 = Bit32(opcode, 11);
2855      uint32_t imm11 = Bits32(opcode, 10, 0);
2856      uint32_t I1 = !(J1 ^ S);
2857      uint32_t I2 = !(J2 ^ S);
2858      uint32_t imm25 =
2859          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2860      imm32 = llvm::SignExtend32<25>(imm25);
2861      target = pc + imm32;
2862      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2863      break;
2864    }
2865    case eEncodingA1:
2866      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2867      target = pc + imm32;
2868      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2869      break;
2870    default:
2871      return false;
2872    }
2873    if (!BranchWritePC(context, target))
2874      return false;
2875  }
2876  return true;
2877}
2878
2879// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2880// value in a register with zero and conditionally branch forward a constant
2881// value.  They do not affect the condition flags. CBNZ, CBZ
2882bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2883                                      const ARMEncoding encoding) {
2884#if 0
2885    // ARM pseudo code...
2886    EncodingSpecificOperations();
2887    if nonzero ^ IsZero(R[n]) then
2888        BranchWritePC(PC + imm32);
2889#endif
2890
2891  bool success = false;
2892
2893  // Read the register value from the operand register Rn.
2894  uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2895  if (!success)
2896    return false;
2897
2898  EmulateInstruction::Context context;
2899  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2900  const uint32_t pc = ReadCoreReg(PC_REG, &success);
2901  if (!success)
2902    return false;
2903
2904  addr_t target;  // target address
2905  uint32_t imm32; // PC-relative offset to branch forward
2906  bool nonzero;
2907  switch (encoding) {
2908  case eEncodingT1:
2909    imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2910    nonzero = BitIsSet(opcode, 11);
2911    target = pc + imm32;
2912    context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2913    break;
2914  default:
2915    return false;
2916  }
2917  if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2918    if (!BranchWritePC(context, target))
2919      return false;
2920
2921  return true;
2922}
2923
2924// Table Branch Byte causes a PC-relative forward branch using a table of
2925// single byte offsets.
2926// A base register provides a pointer to the table, and a second register
2927// supplies an index into the table.
2928// The branch length is twice the value of the byte returned from the table.
2929//
2930// Table Branch Halfword causes a PC-relative forward branch using a table of
2931// single halfword offsets.
2932// A base register provides a pointer to the table, and a second register
2933// supplies an index into the table.
2934// The branch length is twice the value of the halfword returned from the
2935// table. TBB, TBH
2936bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2937                                      const ARMEncoding encoding) {
2938#if 0
2939    // ARM pseudo code...
2940    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2941    if is_tbh then
2942        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2943    else
2944        halfwords = UInt(MemU[R[n]+R[m], 1]);
2945    BranchWritePC(PC + 2*halfwords);
2946#endif
2947
2948  bool success = false;
2949
2950  if (ConditionPassed(opcode)) {
2951    uint32_t Rn; // the base register which contains the address of the table of
2952                 // branch lengths
2953    uint32_t Rm; // the index register which contains an integer pointing to a
2954                 // byte/halfword in the table
2955    bool is_tbh; // true if table branch halfword
2956    switch (encoding) {
2957    case eEncodingT1:
2958      Rn = Bits32(opcode, 19, 16);
2959      Rm = Bits32(opcode, 3, 0);
2960      is_tbh = BitIsSet(opcode, 4);
2961      if (Rn == 13 || BadReg(Rm))
2962        return false;
2963      if (InITBlock() && !LastInITBlock())
2964        return false;
2965      break;
2966    default:
2967      return false;
2968    }
2969
2970    // Read the address of the table from the operand register Rn. The PC can
2971    // be used, in which case the table immediately follows this instruction.
2972    uint32_t base = ReadCoreReg(Rn, &success);
2973    if (!success)
2974      return false;
2975
2976    // the table index
2977    uint32_t index = ReadCoreReg(Rm, &success);
2978    if (!success)
2979      return false;
2980
2981    // the offsetted table address
2982    addr_t addr = base + (is_tbh ? index * 2 : index);
2983
2984    // PC-relative offset to branch forward
2985    EmulateInstruction::Context context;
2986    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2987    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2988    if (!success)
2989      return false;
2990
2991    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2992    if (!success)
2993      return false;
2994
2995    // target address
2996    addr_t target = pc + offset;
2997    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2998    context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
2999
3000    if (!BranchWritePC(context, target))
3001      return false;
3002  }
3003
3004  return true;
3005}
3006
3007// This instruction adds an immediate value to a register value, and writes the
3008// result to the destination register. It can optionally update the condition
3009// flags based on the result.
3010bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3011                                               const ARMEncoding encoding) {
3012#if 0
3013    if ConditionPassed() then
3014        EncodingSpecificOperations();
3015        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3016        R[d] = result;
3017        if setflags then
3018            APSR.N = result<31>;
3019            APSR.Z = IsZeroBit(result);
3020            APSR.C = carry;
3021            APSR.V = overflow;
3022#endif
3023
3024  bool success = false;
3025
3026  if (ConditionPassed(opcode)) {
3027    uint32_t d;
3028    uint32_t n;
3029    bool setflags;
3030    uint32_t imm32;
3031    uint32_t carry_out;
3032
3033    // EncodingSpecificOperations();
3034    switch (encoding) {
3035    case eEncodingT1:
3036      // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3037      // ZeroExtend(imm3, 32);
3038      d = Bits32(opcode, 2, 0);
3039      n = Bits32(opcode, 5, 3);
3040      setflags = !InITBlock();
3041      imm32 = Bits32(opcode, 8, 6);
3042
3043      break;
3044
3045    case eEncodingT2:
3046      // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3047      // ZeroExtend(imm8, 32);
3048      d = Bits32(opcode, 10, 8);
3049      n = Bits32(opcode, 10, 8);
3050      setflags = !InITBlock();
3051      imm32 = Bits32(opcode, 7, 0);
3052
3053      break;
3054
3055    case eEncodingT3:
3056      // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3057      // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3058      // ThumbExpandImm(i:imm3:imm8);
3059      d = Bits32(opcode, 11, 8);
3060      n = Bits32(opcode, 19, 16);
3061      setflags = BitIsSet(opcode, 20);
3062      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3063
3064      // if Rn == '1101' then SEE ADD (SP plus immediate);
3065      if (n == 13)
3066        return EmulateADDSPImm(opcode, eEncodingT3);
3067
3068      // if BadReg(d) || n == 15 then UNPREDICTABLE;
3069      if (BadReg(d) || (n == 15))
3070        return false;
3071
3072      break;
3073
3074    case eEncodingT4: {
3075      // if Rn == '1111' then SEE ADR;
3076      // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3077      // ZeroExtend(i:imm3:imm8, 32);
3078      d = Bits32(opcode, 11, 8);
3079      n = Bits32(opcode, 19, 16);
3080      setflags = false;
3081      uint32_t i = Bit32(opcode, 26);
3082      uint32_t imm3 = Bits32(opcode, 14, 12);
3083      uint32_t imm8 = Bits32(opcode, 7, 0);
3084      imm32 = (i << 11) | (imm3 << 8) | imm8;
3085
3086      // if Rn == '1101' then SEE ADD (SP plus immediate);
3087      if (n == 13)
3088        return EmulateADDSPImm(opcode, eEncodingT4);
3089
3090      // if BadReg(d) then UNPREDICTABLE;
3091      if (BadReg(d))
3092        return false;
3093
3094      break;
3095    }
3096
3097    default:
3098      return false;
3099    }
3100
3101    uint64_t Rn =
3102        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3103    if (!success)
3104      return false;
3105
3106    //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3107    AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3108
3109    std::optional<RegisterInfo> reg_n =
3110        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
3111    EmulateInstruction::Context context;
3112    context.type = eContextArithmetic;
3113    context.SetRegisterPlusOffset(*reg_n, imm32);
3114
3115    // R[d] = result;
3116    // if setflags then
3117    // APSR.N = result<31>;
3118    // APSR.Z = IsZeroBit(result);
3119    // APSR.C = carry;
3120    // APSR.V = overflow;
3121    if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3122                                   res.carry_out, res.overflow))
3123      return false;
3124  }
3125  return true;
3126}
3127
3128// This instruction adds an immediate value to a register value, and writes the
3129// result to the destination register.  It can optionally update the condition
3130// flags based on the result.
3131bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3132                                             const ARMEncoding encoding) {
3133#if 0
3134    // ARM pseudo code...
3135    if ConditionPassed() then
3136        EncodingSpecificOperations();
3137        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3138        if d == 15 then
3139            ALUWritePC(result); // setflags is always FALSE here
3140        else
3141            R[d] = result;
3142            if setflags then
3143                APSR.N = result<31>;
3144                APSR.Z = IsZeroBit(result);
3145                APSR.C = carry;
3146                APSR.V = overflow;
3147#endif
3148
3149  bool success = false;
3150
3151  if (ConditionPassed(opcode)) {
3152    uint32_t Rd, Rn;
3153    uint32_t
3154        imm32; // the immediate value to be added to the value obtained from Rn
3155    bool setflags;
3156    switch (encoding) {
3157    case eEncodingA1:
3158      Rd = Bits32(opcode, 15, 12);
3159      Rn = Bits32(opcode, 19, 16);
3160      setflags = BitIsSet(opcode, 20);
3161      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3162      break;
3163    default:
3164      return false;
3165    }
3166
3167    // Read the first operand.
3168    uint32_t val1 = ReadCoreReg(Rn, &success);
3169    if (!success)
3170      return false;
3171
3172    AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3173
3174    EmulateInstruction::Context context;
3175    if (Rd == 13)
3176      context.type = EmulateInstruction::eContextAdjustStackPointer;
3177    else if (Rd == GetFramePointerRegisterNumber())
3178      context.type = EmulateInstruction::eContextSetFramePointer;
3179    else
3180      context.type = EmulateInstruction::eContextRegisterPlusOffset;
3181
3182    std::optional<RegisterInfo> dwarf_reg =
3183        GetRegisterInfo(eRegisterKindDWARF, Rn);
3184    context.SetRegisterPlusOffset(*dwarf_reg, imm32);
3185
3186    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3187                                   res.carry_out, res.overflow))
3188      return false;
3189  }
3190  return true;
3191}
3192
3193// This instruction adds a register value and an optionally-shifted register
3194// value, and writes the result to the destination register. It can optionally
3195// update the condition flags based on the result.
3196bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3197                                          const ARMEncoding encoding) {
3198#if 0
3199    // ARM pseudo code...
3200    if ConditionPassed() then
3201        EncodingSpecificOperations();
3202        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3203        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3204        if d == 15 then
3205            ALUWritePC(result); // setflags is always FALSE here
3206        else
3207            R[d] = result;
3208            if setflags then
3209                APSR.N = result<31>;
3210                APSR.Z = IsZeroBit(result);
3211                APSR.C = carry;
3212                APSR.V = overflow;
3213#endif
3214
3215  bool success = false;
3216
3217  if (ConditionPassed(opcode)) {
3218    uint32_t Rd, Rn, Rm;
3219    ARM_ShifterType shift_t;
3220    uint32_t shift_n; // the shift applied to the value read from Rm
3221    bool setflags;
3222    switch (encoding) {
3223    case eEncodingT1:
3224      Rd = Bits32(opcode, 2, 0);
3225      Rn = Bits32(opcode, 5, 3);
3226      Rm = Bits32(opcode, 8, 6);
3227      setflags = !InITBlock();
3228      shift_t = SRType_LSL;
3229      shift_n = 0;
3230      break;
3231    case eEncodingT2:
3232      Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3233      Rm = Bits32(opcode, 6, 3);
3234      setflags = false;
3235      shift_t = SRType_LSL;
3236      shift_n = 0;
3237      if (Rn == 15 && Rm == 15)
3238        return false;
3239      if (Rd == 15 && InITBlock() && !LastInITBlock())
3240        return false;
3241      break;
3242    case eEncodingA1:
3243      Rd = Bits32(opcode, 15, 12);
3244      Rn = Bits32(opcode, 19, 16);
3245      Rm = Bits32(opcode, 3, 0);
3246      setflags = BitIsSet(opcode, 20);
3247      shift_n = DecodeImmShiftARM(opcode, shift_t);
3248      break;
3249    default:
3250      return false;
3251    }
3252
3253    // Read the first operand.
3254    uint32_t val1 = ReadCoreReg(Rn, &success);
3255    if (!success)
3256      return false;
3257
3258    // Read the second operand.
3259    uint32_t val2 = ReadCoreReg(Rm, &success);
3260    if (!success)
3261      return false;
3262
3263    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3264    if (!success)
3265      return false;
3266    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3267
3268    EmulateInstruction::Context context;
3269    context.type = eContextArithmetic;
3270    std::optional<RegisterInfo> op1_reg =
3271        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn);
3272    std::optional<RegisterInfo> op2_reg =
3273        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
3274    context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
3275
3276    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3277                                   res.carry_out, res.overflow))
3278      return false;
3279  }
3280  return true;
3281}
3282
3283// Compare Negative (immediate) adds a register value and an immediate value.
3284// It updates the condition flags based on the result, and discards the result.
3285bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3286                                          const ARMEncoding encoding) {
3287#if 0
3288    // ARM pseudo code...
3289    if ConditionPassed() then
3290        EncodingSpecificOperations();
3291        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3292        APSR.N = result<31>;
3293        APSR.Z = IsZeroBit(result);
3294        APSR.C = carry;
3295        APSR.V = overflow;
3296#endif
3297
3298  bool success = false;
3299
3300  uint32_t Rn;    // the first operand
3301  uint32_t imm32; // the immediate value to be compared with
3302  switch (encoding) {
3303  case eEncodingT1:
3304    Rn = Bits32(opcode, 19, 16);
3305    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3306    if (Rn == 15)
3307      return false;
3308    break;
3309  case eEncodingA1:
3310    Rn = Bits32(opcode, 19, 16);
3311    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3312    break;
3313  default:
3314    return false;
3315  }
3316  // Read the register value from the operand register Rn.
3317  uint32_t reg_val = ReadCoreReg(Rn, &success);
3318  if (!success)
3319    return false;
3320
3321  AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3322
3323  EmulateInstruction::Context context;
3324  context.type = EmulateInstruction::eContextImmediate;
3325  context.SetNoArgs();
3326  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3327}
3328
3329// Compare Negative (register) adds a register value and an optionally-shifted
3330// register value. It updates the condition flags based on the result, and
3331// discards the result.
3332bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3333                                          const ARMEncoding encoding) {
3334#if 0
3335    // ARM pseudo code...
3336    if ConditionPassed() then
3337        EncodingSpecificOperations();
3338        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3339        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3340        APSR.N = result<31>;
3341        APSR.Z = IsZeroBit(result);
3342        APSR.C = carry;
3343        APSR.V = overflow;
3344#endif
3345
3346  bool success = false;
3347
3348  uint32_t Rn; // the first operand
3349  uint32_t Rm; // the second operand
3350  ARM_ShifterType shift_t;
3351  uint32_t shift_n; // the shift applied to the value read from Rm
3352  switch (encoding) {
3353  case eEncodingT1:
3354    Rn = Bits32(opcode, 2, 0);
3355    Rm = Bits32(opcode, 5, 3);
3356    shift_t = SRType_LSL;
3357    shift_n = 0;
3358    break;
3359  case eEncodingT2:
3360    Rn = Bits32(opcode, 19, 16);
3361    Rm = Bits32(opcode, 3, 0);
3362    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3363    // if n == 15 || BadReg(m) then UNPREDICTABLE;
3364    if (Rn == 15 || BadReg(Rm))
3365      return false;
3366    break;
3367  case eEncodingA1:
3368    Rn = Bits32(opcode, 19, 16);
3369    Rm = Bits32(opcode, 3, 0);
3370    shift_n = DecodeImmShiftARM(opcode, shift_t);
3371    break;
3372  default:
3373    return false;
3374  }
3375  // Read the register value from register Rn.
3376  uint32_t val1 = ReadCoreReg(Rn, &success);
3377  if (!success)
3378    return false;
3379
3380  // Read the register value from register Rm.
3381  uint32_t val2 = ReadCoreReg(Rm, &success);
3382  if (!success)
3383    return false;
3384
3385  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3386  if (!success)
3387    return false;
3388  AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3389
3390  EmulateInstruction::Context context;
3391  context.type = EmulateInstruction::eContextImmediate;
3392  context.SetNoArgs();
3393  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3394}
3395
3396// Compare (immediate) subtracts an immediate value from a register value. It
3397// updates the condition flags based on the result, and discards the result.
3398bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3399                                          const ARMEncoding encoding) {
3400#if 0
3401    // ARM pseudo code...
3402    if ConditionPassed() then
3403        EncodingSpecificOperations();
3404        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3405        APSR.N = result<31>;
3406        APSR.Z = IsZeroBit(result);
3407        APSR.C = carry;
3408        APSR.V = overflow;
3409#endif
3410
3411  bool success = false;
3412
3413  uint32_t Rn;    // the first operand
3414  uint32_t imm32; // the immediate value to be compared with
3415  switch (encoding) {
3416  case eEncodingT1:
3417    Rn = Bits32(opcode, 10, 8);
3418    imm32 = Bits32(opcode, 7, 0);
3419    break;
3420  case eEncodingT2:
3421    Rn = Bits32(opcode, 19, 16);
3422    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3423    if (Rn == 15)
3424      return false;
3425    break;
3426  case eEncodingA1:
3427    Rn = Bits32(opcode, 19, 16);
3428    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3429    break;
3430  default:
3431    return false;
3432  }
3433  // Read the register value from the operand register Rn.
3434  uint32_t reg_val = ReadCoreReg(Rn, &success);
3435  if (!success)
3436    return false;
3437
3438  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3439
3440  EmulateInstruction::Context context;
3441  context.type = EmulateInstruction::eContextImmediate;
3442  context.SetNoArgs();
3443  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3444}
3445
3446// Compare (register) subtracts an optionally-shifted register value from a
3447// register value. It updates the condition flags based on the result, and
3448// discards the result.
3449bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3450                                          const ARMEncoding encoding) {
3451#if 0
3452    // ARM pseudo code...
3453    if ConditionPassed() then
3454        EncodingSpecificOperations();
3455        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3456        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3457        APSR.N = result<31>;
3458        APSR.Z = IsZeroBit(result);
3459        APSR.C = carry;
3460        APSR.V = overflow;
3461#endif
3462
3463  bool success = false;
3464
3465  uint32_t Rn; // the first operand
3466  uint32_t Rm; // the second operand
3467  ARM_ShifterType shift_t;
3468  uint32_t shift_n; // the shift applied to the value read from Rm
3469  switch (encoding) {
3470  case eEncodingT1:
3471    Rn = Bits32(opcode, 2, 0);
3472    Rm = Bits32(opcode, 5, 3);
3473    shift_t = SRType_LSL;
3474    shift_n = 0;
3475    break;
3476  case eEncodingT2:
3477    Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3478    Rm = Bits32(opcode, 6, 3);
3479    shift_t = SRType_LSL;
3480    shift_n = 0;
3481    if (Rn < 8 && Rm < 8)
3482      return false;
3483    if (Rn == 15 || Rm == 15)
3484      return false;
3485    break;
3486  case eEncodingT3:
3487    Rn = Bits32(opcode, 19, 16);
3488    Rm = Bits32(opcode, 3, 0);
3489    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3490    if (Rn == 15 || BadReg(Rm))
3491      return false;
3492    break;
3493  case eEncodingA1:
3494    Rn = Bits32(opcode, 19, 16);
3495    Rm = Bits32(opcode, 3, 0);
3496    shift_n = DecodeImmShiftARM(opcode, shift_t);
3497    break;
3498  default:
3499    return false;
3500  }
3501  // Read the register value from register Rn.
3502  uint32_t val1 = ReadCoreReg(Rn, &success);
3503  if (!success)
3504    return false;
3505
3506  // Read the register value from register Rm.
3507  uint32_t val2 = ReadCoreReg(Rm, &success);
3508  if (!success)
3509    return false;
3510
3511  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3512  if (!success)
3513    return false;
3514  AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3515
3516  EmulateInstruction::Context context;
3517  context.type = EmulateInstruction::eContextImmediate;
3518  context.SetNoArgs();
3519  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3520}
3521
3522// Arithmetic Shift Right (immediate) shifts a register value right by an
3523// immediate number of bits, shifting in copies of its sign bit, and writes the
3524// result to the destination register.  It can optionally update the condition
3525// flags based on the result.
3526bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3527                                          const ARMEncoding encoding) {
3528#if 0
3529    // ARM pseudo code...
3530    if ConditionPassed() then
3531        EncodingSpecificOperations();
3532        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3533        if d == 15 then         // Can only occur for ARM encoding
3534            ALUWritePC(result); // setflags is always FALSE here
3535        else
3536            R[d] = result;
3537            if setflags then
3538                APSR.N = result<31>;
3539                APSR.Z = IsZeroBit(result);
3540                APSR.C = carry;
3541                // APSR.V unchanged
3542#endif
3543
3544  return EmulateShiftImm(opcode, encoding, SRType_ASR);
3545}
3546
3547// Arithmetic Shift Right (register) shifts a register value right by a
3548// variable number of bits, shifting in copies of its sign bit, and writes the
3549// result to the destination register. The variable number of bits is read from
3550// the bottom byte of a register. It can optionally update the condition flags
3551// based on the result.
3552bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3553                                          const ARMEncoding encoding) {
3554#if 0
3555    // ARM pseudo code...
3556    if ConditionPassed() then
3557        EncodingSpecificOperations();
3558        shift_n = UInt(R[m]<7:0>);
3559        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3560        R[d] = result;
3561        if setflags then
3562            APSR.N = result<31>;
3563            APSR.Z = IsZeroBit(result);
3564            APSR.C = carry;
3565            // APSR.V unchanged
3566#endif
3567
3568  return EmulateShiftReg(opcode, encoding, SRType_ASR);
3569}
3570
3571// Logical Shift Left (immediate) shifts a register value left by an immediate
3572// number of bits, shifting in zeros, and writes the result to the destination
3573// register.  It can optionally update the condition flags based on the result.
3574bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3575                                          const ARMEncoding encoding) {
3576#if 0
3577    // ARM pseudo code...
3578    if ConditionPassed() then
3579        EncodingSpecificOperations();
3580        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3581        if d == 15 then         // Can only occur for ARM encoding
3582            ALUWritePC(result); // setflags is always FALSE here
3583        else
3584            R[d] = result;
3585            if setflags then
3586                APSR.N = result<31>;
3587                APSR.Z = IsZeroBit(result);
3588                APSR.C = carry;
3589                // APSR.V unchanged
3590#endif
3591
3592  return EmulateShiftImm(opcode, encoding, SRType_LSL);
3593}
3594
3595// Logical Shift Left (register) shifts a register value left by a variable
3596// number of bits, shifting in zeros, and writes the result to the destination
3597// register.  The variable number of bits is read from the bottom byte of a
3598// register. It can optionally update the condition flags based on the result.
3599bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3600                                          const ARMEncoding encoding) {
3601#if 0
3602    // ARM pseudo code...
3603    if ConditionPassed() then
3604        EncodingSpecificOperations();
3605        shift_n = UInt(R[m]<7:0>);
3606        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3607        R[d] = result;
3608        if setflags then
3609            APSR.N = result<31>;
3610            APSR.Z = IsZeroBit(result);
3611            APSR.C = carry;
3612            // APSR.V unchanged
3613#endif
3614
3615  return EmulateShiftReg(opcode, encoding, SRType_LSL);
3616}
3617
3618// Logical Shift Right (immediate) shifts a register value right by an
3619// immediate number of bits, shifting in zeros, and writes the result to the
3620// destination register.  It can optionally update the condition flags based on
3621// the result.
3622bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3623                                          const ARMEncoding encoding) {
3624#if 0
3625    // ARM pseudo code...
3626    if ConditionPassed() then
3627        EncodingSpecificOperations();
3628        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3629        if d == 15 then         // Can only occur for ARM encoding
3630            ALUWritePC(result); // setflags is always FALSE here
3631        else
3632            R[d] = result;
3633            if setflags then
3634                APSR.N = result<31>;
3635                APSR.Z = IsZeroBit(result);
3636                APSR.C = carry;
3637                // APSR.V unchanged
3638#endif
3639
3640  return EmulateShiftImm(opcode, encoding, SRType_LSR);
3641}
3642
3643// Logical Shift Right (register) shifts a register value right by a variable
3644// number of bits, shifting in zeros, and writes the result to the destination
3645// register.  The variable number of bits is read from the bottom byte of a
3646// register. It can optionally update the condition flags based on the result.
3647bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3648                                          const ARMEncoding encoding) {
3649#if 0
3650    // ARM pseudo code...
3651    if ConditionPassed() then
3652        EncodingSpecificOperations();
3653        shift_n = UInt(R[m]<7:0>);
3654        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3655        R[d] = result;
3656        if setflags then
3657            APSR.N = result<31>;
3658            APSR.Z = IsZeroBit(result);
3659            APSR.C = carry;
3660            // APSR.V unchanged
3661#endif
3662
3663  return EmulateShiftReg(opcode, encoding, SRType_LSR);
3664}
3665
3666// Rotate Right (immediate) provides the value of the contents of a register
3667// rotated by a constant value. The bits that are rotated off the right end are
3668// inserted into the vacated bit positions on the left. It can optionally
3669// update the condition flags based on the result.
3670bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3671                                          const ARMEncoding encoding) {
3672#if 0
3673    // ARM pseudo code...
3674    if ConditionPassed() then
3675        EncodingSpecificOperations();
3676        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3677        if d == 15 then         // Can only occur for ARM encoding
3678            ALUWritePC(result); // setflags is always FALSE here
3679        else
3680            R[d] = result;
3681            if setflags then
3682                APSR.N = result<31>;
3683                APSR.Z = IsZeroBit(result);
3684                APSR.C = carry;
3685                // APSR.V unchanged
3686#endif
3687
3688  return EmulateShiftImm(opcode, encoding, SRType_ROR);
3689}
3690
3691// Rotate Right (register) provides the value of the contents of a register
3692// rotated by a variable number of bits. The bits that are rotated off the
3693// right end are inserted into the vacated bit positions on the left. The
3694// variable number of bits is read from the bottom byte of a register. It can
3695// optionally update the condition flags based on the result.
3696bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3697                                          const ARMEncoding encoding) {
3698#if 0
3699    // ARM pseudo code...
3700    if ConditionPassed() then
3701        EncodingSpecificOperations();
3702        shift_n = UInt(R[m]<7:0>);
3703        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3704        R[d] = result;
3705        if setflags then
3706            APSR.N = result<31>;
3707            APSR.Z = IsZeroBit(result);
3708            APSR.C = carry;
3709            // APSR.V unchanged
3710#endif
3711
3712  return EmulateShiftReg(opcode, encoding, SRType_ROR);
3713}
3714
3715// Rotate Right with Extend provides the value of the contents of a register
3716// shifted right by one place, with the carry flag shifted into bit [31].
3717//
3718// RRX can optionally update the condition flags based on the result.
3719// In that case, bit [0] is shifted into the carry flag.
3720bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3721                                       const ARMEncoding encoding) {
3722#if 0
3723    // ARM pseudo code...
3724    if ConditionPassed() then
3725        EncodingSpecificOperations();
3726        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3727        if d == 15 then         // Can only occur for ARM encoding
3728            ALUWritePC(result); // setflags is always FALSE here
3729        else
3730            R[d] = result;
3731            if setflags then
3732                APSR.N = result<31>;
3733                APSR.Z = IsZeroBit(result);
3734                APSR.C = carry;
3735                // APSR.V unchanged
3736#endif
3737
3738  return EmulateShiftImm(opcode, encoding, SRType_RRX);
3739}
3740
3741bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3742                                            const ARMEncoding encoding,
3743                                            ARM_ShifterType shift_type) {
3744  //    assert(shift_type == SRType_ASR
3745  //           || shift_type == SRType_LSL
3746  //           || shift_type == SRType_LSR
3747  //           || shift_type == SRType_ROR
3748  //           || shift_type == SRType_RRX);
3749
3750  bool success = false;
3751
3752  if (ConditionPassed(opcode)) {
3753    uint32_t Rd;    // the destination register
3754    uint32_t Rm;    // the first operand register
3755    uint32_t imm5;  // encoding for the shift amount
3756    uint32_t carry; // the carry bit after the shift operation
3757    bool setflags;
3758
3759    // Special case handling!
3760    // A8.6.139 ROR (immediate) -- Encoding T1
3761    ARMEncoding use_encoding = encoding;
3762    if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3763      // Morph the T1 encoding from the ARM Architecture Manual into T2
3764      // encoding to have the same decoding of bit fields as the other Thumb2
3765      // shift operations.
3766      use_encoding = eEncodingT2;
3767    }
3768
3769    switch (use_encoding) {
3770    case eEncodingT1:
3771      Rd = Bits32(opcode, 2, 0);
3772      Rm = Bits32(opcode, 5, 3);
3773      setflags = !InITBlock();
3774      imm5 = Bits32(opcode, 10, 6);
3775      break;
3776    case eEncodingT2:
3777      // A8.6.141 RRX
3778      // There's no imm form of RRX instructions.
3779      if (shift_type == SRType_RRX)
3780        return false;
3781
3782      Rd = Bits32(opcode, 11, 8);
3783      Rm = Bits32(opcode, 3, 0);
3784      setflags = BitIsSet(opcode, 20);
3785      imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3786      if (BadReg(Rd) || BadReg(Rm))
3787        return false;
3788      break;
3789    case eEncodingA1:
3790      Rd = Bits32(opcode, 15, 12);
3791      Rm = Bits32(opcode, 3, 0);
3792      setflags = BitIsSet(opcode, 20);
3793      imm5 = Bits32(opcode, 11, 7);
3794      break;
3795    default:
3796      return false;
3797    }
3798
3799    // A8.6.139 ROR (immediate)
3800    if (shift_type == SRType_ROR && imm5 == 0)
3801      shift_type = SRType_RRX;
3802
3803    // Get the first operand.
3804    uint32_t value = ReadCoreReg(Rm, &success);
3805    if (!success)
3806      return false;
3807
3808    // Decode the shift amount if not RRX.
3809    uint32_t amt =
3810        (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3811
3812    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3813    if (!success)
3814      return false;
3815
3816    // The context specifies that an immediate is to be moved into Rd.
3817    EmulateInstruction::Context context;
3818    context.type = EmulateInstruction::eContextImmediate;
3819    context.SetNoArgs();
3820
3821    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3822      return false;
3823  }
3824  return true;
3825}
3826
3827bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3828                                            const ARMEncoding encoding,
3829                                            ARM_ShifterType shift_type) {
3830  // assert(shift_type == SRType_ASR
3831  //        || shift_type == SRType_LSL
3832  //        || shift_type == SRType_LSR
3833  //        || shift_type == SRType_ROR);
3834
3835  bool success = false;
3836
3837  if (ConditionPassed(opcode)) {
3838    uint32_t Rd; // the destination register
3839    uint32_t Rn; // the first operand register
3840    uint32_t
3841        Rm; // the register whose bottom byte contains the amount to shift by
3842    uint32_t carry; // the carry bit after the shift operation
3843    bool setflags;
3844    switch (encoding) {
3845    case eEncodingT1:
3846      Rd = Bits32(opcode, 2, 0);
3847      Rn = Rd;
3848      Rm = Bits32(opcode, 5, 3);
3849      setflags = !InITBlock();
3850      break;
3851    case eEncodingT2:
3852      Rd = Bits32(opcode, 11, 8);
3853      Rn = Bits32(opcode, 19, 16);
3854      Rm = Bits32(opcode, 3, 0);
3855      setflags = BitIsSet(opcode, 20);
3856      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3857        return false;
3858      break;
3859    case eEncodingA1:
3860      Rd = Bits32(opcode, 15, 12);
3861      Rn = Bits32(opcode, 3, 0);
3862      Rm = Bits32(opcode, 11, 8);
3863      setflags = BitIsSet(opcode, 20);
3864      if (Rd == 15 || Rn == 15 || Rm == 15)
3865        return false;
3866      break;
3867    default:
3868      return false;
3869    }
3870
3871    // Get the first operand.
3872    uint32_t value = ReadCoreReg(Rn, &success);
3873    if (!success)
3874      return false;
3875    // Get the Rm register content.
3876    uint32_t val = ReadCoreReg(Rm, &success);
3877    if (!success)
3878      return false;
3879
3880    // Get the shift amount.
3881    uint32_t amt = Bits32(val, 7, 0);
3882
3883    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3884    if (!success)
3885      return false;
3886
3887    // The context specifies that an immediate is to be moved into Rd.
3888    EmulateInstruction::Context context;
3889    context.type = EmulateInstruction::eContextImmediate;
3890    context.SetNoArgs();
3891
3892    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3893      return false;
3894  }
3895  return true;
3896}
3897
3898// LDM loads multiple registers from consecutive memory locations, using an
3899// address from a base register.  Optionally the address just above the highest
3900// of those locations can be written back to the base register.
3901bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3902                                       const ARMEncoding encoding) {
3903#if 0
3904    // ARM pseudo code...
3905    if ConditionPassed()
3906        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3907        address = R[n];
3908
3909        for i = 0 to 14
3910            if registers<i> == '1' then
3911                R[i] = MemA[address, 4]; address = address + 4;
3912        if registers<15> == '1' then
3913            LoadWritePC (MemA[address, 4]);
3914
3915        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3916        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3917
3918#endif
3919
3920  bool success = false;
3921  if (ConditionPassed(opcode)) {
3922    uint32_t n;
3923    uint32_t registers = 0;
3924    bool wback;
3925    const uint32_t addr_byte_size = GetAddressByteSize();
3926    switch (encoding) {
3927    case eEncodingT1:
3928      // n = UInt(Rn); registers = '00000000':register_list; wback =
3929      // (registers<n> == '0');
3930      n = Bits32(opcode, 10, 8);
3931      registers = Bits32(opcode, 7, 0);
3932      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3933      wback = BitIsClear(registers, n);
3934      // if BitCount(registers) < 1 then UNPREDICTABLE;
3935      if (BitCount(registers) < 1)
3936        return false;
3937      break;
3938    case eEncodingT2:
3939      // if W == '1' && Rn == '1101' then SEE POP;
3940      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3941      n = Bits32(opcode, 19, 16);
3942      registers = Bits32(opcode, 15, 0);
3943      registers = registers & 0xdfff; // Make sure bit 13 is zero.
3944      wback = BitIsSet(opcode, 21);
3945
3946      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3947      // UNPREDICTABLE;
3948      if ((n == 15) || (BitCount(registers) < 2) ||
3949          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3950        return false;
3951
3952      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3953      // UNPREDICTABLE;
3954      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3955        return false;
3956
3957      // if wback && registers<n> == '1' then UNPREDICTABLE;
3958      if (wback && BitIsSet(registers, n))
3959        return false;
3960      break;
3961
3962    case eEncodingA1:
3963      n = Bits32(opcode, 19, 16);
3964      registers = Bits32(opcode, 15, 0);
3965      wback = BitIsSet(opcode, 21);
3966      if ((n == 15) || (BitCount(registers) < 1))
3967        return false;
3968      break;
3969    default:
3970      return false;
3971    }
3972
3973    int32_t offset = 0;
3974    const addr_t base_address =
3975        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3976    if (!success)
3977      return false;
3978
3979    EmulateInstruction::Context context;
3980    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3981    std::optional<RegisterInfo> dwarf_reg =
3982        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
3983    context.SetRegisterPlusOffset(*dwarf_reg, offset);
3984
3985    for (int i = 0; i < 14; ++i) {
3986      if (BitIsSet(registers, i)) {
3987        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3988        context.SetRegisterPlusOffset(*dwarf_reg, offset);
3989        if (wback && (n == 13)) // Pop Instruction
3990        {
3991          context.type = EmulateInstruction::eContextPopRegisterOffStack;
3992          context.SetAddress(base_address + offset);
3993        }
3994
3995        // R[i] = MemA [address, 4]; address = address + 4;
3996        uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
3997                                 0, &success);
3998        if (!success)
3999          return false;
4000
4001        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4002                                   data))
4003          return false;
4004
4005        offset += addr_byte_size;
4006      }
4007    }
4008
4009    if (BitIsSet(registers, 15)) {
4010      // LoadWritePC (MemA [address, 4]);
4011      context.type = EmulateInstruction::eContextRegisterPlusOffset;
4012      context.SetRegisterPlusOffset(*dwarf_reg, offset);
4013      uint32_t data =
4014          MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4015      if (!success)
4016        return false;
4017      // In ARMv5T and above, this is an interworking branch.
4018      if (!LoadWritePC(context, data))
4019        return false;
4020    }
4021
4022    if (wback && BitIsClear(registers, n)) {
4023      // R[n] = R[n] + 4 * BitCount (registers)
4024      int32_t offset = addr_byte_size * BitCount(registers);
4025      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4026      context.SetRegisterPlusOffset(*dwarf_reg, offset);
4027
4028      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4029                                 base_address + offset))
4030        return false;
4031    }
4032    if (wback && BitIsSet(registers, n))
4033      // R[n] bits(32) UNKNOWN;
4034      return WriteBits32Unknown(n);
4035  }
4036  return true;
4037}
4038
4039// LDMDA loads multiple registers from consecutive memory locations using an
4040// address from a base register.
4041// The consecutive memory locations end at this address and the address just
4042// below the lowest of those locations can optionally be written back to the
4043// base register.
4044bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4045                                         const ARMEncoding encoding) {
4046#if 0
4047    // ARM pseudo code...
4048    if ConditionPassed() then
4049        EncodingSpecificOperations();
4050        address = R[n] - 4*BitCount(registers) + 4;
4051
4052        for i = 0 to 14
4053            if registers<i> == '1' then
4054                  R[i] = MemA[address,4]; address = address + 4;
4055
4056        if registers<15> == '1' then
4057            LoadWritePC(MemA[address,4]);
4058
4059        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4060        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4061#endif
4062
4063  bool success = false;
4064
4065  if (ConditionPassed(opcode)) {
4066    uint32_t n;
4067    uint32_t registers = 0;
4068    bool wback;
4069    const uint32_t addr_byte_size = GetAddressByteSize();
4070
4071    // EncodingSpecificOperations();
4072    switch (encoding) {
4073    case eEncodingA1:
4074      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4075      n = Bits32(opcode, 19, 16);
4076      registers = Bits32(opcode, 15, 0);
4077      wback = BitIsSet(opcode, 21);
4078
4079      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4080      if ((n == 15) || (BitCount(registers) < 1))
4081        return false;
4082
4083      break;
4084
4085    default:
4086      return false;
4087    }
4088    // address = R[n] - 4*BitCount(registers) + 4;
4089
4090    int32_t offset = 0;
4091    addr_t Rn = ReadCoreReg(n, &success);
4092
4093    if (!success)
4094      return false;
4095
4096    addr_t address =
4097        Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4098
4099    EmulateInstruction::Context context;
4100    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4101    std::optional<RegisterInfo> dwarf_reg =
4102        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4103    context.SetRegisterPlusOffset(*dwarf_reg, offset);
4104
4105    // for i = 0 to 14
4106    for (int i = 0; i < 14; ++i) {
4107      // if registers<i> == '1' then
4108      if (BitIsSet(registers, i)) {
4109        // R[i] = MemA[address,4]; address = address + 4;
4110        context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4111        uint32_t data =
4112            MemARead(context, address + offset, addr_byte_size, 0, &success);
4113        if (!success)
4114          return false;
4115        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4116                                   data))
4117          return false;
4118        offset += addr_byte_size;
4119      }
4120    }
4121
4122    // if registers<15> == '1' then
4123    //     LoadWritePC(MemA[address,4]);
4124    if (BitIsSet(registers, 15)) {
4125      context.SetRegisterPlusOffset(*dwarf_reg, offset);
4126      uint32_t data =
4127          MemARead(context, address + offset, addr_byte_size, 0, &success);
4128      if (!success)
4129        return false;
4130      // In ARMv5T and above, this is an interworking branch.
4131      if (!LoadWritePC(context, data))
4132        return false;
4133    }
4134
4135    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4136    if (wback && BitIsClear(registers, n)) {
4137
4138      offset = (addr_byte_size * BitCount(registers)) * -1;
4139      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4140      context.SetImmediateSigned(offset);
4141      addr_t addr = Rn + offset;
4142      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4143                                 addr))
4144        return false;
4145    }
4146
4147    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4148    if (wback && BitIsSet(registers, n))
4149      return WriteBits32Unknown(n);
4150  }
4151  return true;
4152}
4153
4154// LDMDB loads multiple registers from consecutive memory locations using an
4155// address from a base register.  The
4156// consecutive memory locations end just below this address, and the address of
4157// the lowest of those locations can be optionally written back to the base
4158// register.
4159bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4160                                         const ARMEncoding encoding) {
4161#if 0
4162    // ARM pseudo code...
4163    if ConditionPassed() then
4164        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4165        address = R[n] - 4*BitCount(registers);
4166
4167        for i = 0 to 14
4168            if registers<i> == '1' then
4169                  R[i] = MemA[address,4]; address = address + 4;
4170        if registers<15> == '1' then
4171                  LoadWritePC(MemA[address,4]);
4172
4173        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4174        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4175#endif
4176
4177  bool success = false;
4178
4179  if (ConditionPassed(opcode)) {
4180    uint32_t n;
4181    uint32_t registers = 0;
4182    bool wback;
4183    const uint32_t addr_byte_size = GetAddressByteSize();
4184    switch (encoding) {
4185    case eEncodingT1:
4186      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4187      n = Bits32(opcode, 19, 16);
4188      registers = Bits32(opcode, 15, 0);
4189      registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4190      wback = BitIsSet(opcode, 21);
4191
4192      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4193      // UNPREDICTABLE;
4194      if ((n == 15) || (BitCount(registers) < 2) ||
4195          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4196        return false;
4197
4198      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4199      // UNPREDICTABLE;
4200      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4201        return false;
4202
4203      // if wback && registers<n> == '1' then UNPREDICTABLE;
4204      if (wback && BitIsSet(registers, n))
4205        return false;
4206
4207      break;
4208
4209    case eEncodingA1:
4210      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4211      n = Bits32(opcode, 19, 16);
4212      registers = Bits32(opcode, 15, 0);
4213      wback = BitIsSet(opcode, 21);
4214
4215      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4216      if ((n == 15) || (BitCount(registers) < 1))
4217        return false;
4218
4219      break;
4220
4221    default:
4222      return false;
4223    }
4224
4225    // address = R[n] - 4*BitCount(registers);
4226
4227    int32_t offset = 0;
4228    addr_t Rn =
4229        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4230
4231    if (!success)
4232      return false;
4233
4234    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4235    EmulateInstruction::Context context;
4236    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4237    std::optional<RegisterInfo> dwarf_reg =
4238        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4239    context.SetRegisterPlusOffset(*dwarf_reg, Rn - address);
4240
4241    for (int i = 0; i < 14; ++i) {
4242      if (BitIsSet(registers, i)) {
4243        // R[i] = MemA[address,4]; address = address + 4;
4244        context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4245        uint32_t data =
4246            MemARead(context, address + offset, addr_byte_size, 0, &success);
4247        if (!success)
4248          return false;
4249
4250        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4251                                   data))
4252          return false;
4253
4254        offset += addr_byte_size;
4255      }
4256    }
4257
4258    // if registers<15> == '1' then
4259    //     LoadWritePC(MemA[address,4]);
4260    if (BitIsSet(registers, 15)) {
4261      context.SetRegisterPlusOffset(*dwarf_reg, offset);
4262      uint32_t data =
4263          MemARead(context, address + offset, addr_byte_size, 0, &success);
4264      if (!success)
4265        return false;
4266      // In ARMv5T and above, this is an interworking branch.
4267      if (!LoadWritePC(context, data))
4268        return false;
4269    }
4270
4271    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4272    if (wback && BitIsClear(registers, n)) {
4273
4274      offset = (addr_byte_size * BitCount(registers)) * -1;
4275      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4276      context.SetImmediateSigned(offset);
4277      addr_t addr = Rn + offset;
4278      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4279                                 addr))
4280        return false;
4281    }
4282
4283    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4284    // possible for encoding A1
4285    if (wback && BitIsSet(registers, n))
4286      return WriteBits32Unknown(n);
4287  }
4288  return true;
4289}
4290
4291// LDMIB loads multiple registers from consecutive memory locations using an
4292// address from a base register.  The
4293// consecutive memory locations start just above this address, and thea ddress
4294// of the last of those locations can optinoally be written back to the base
4295// register.
4296bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4297                                         const ARMEncoding encoding) {
4298#if 0
4299    if ConditionPassed() then
4300        EncodingSpecificOperations();
4301        address = R[n] + 4;
4302
4303        for i = 0 to 14
4304            if registers<i> == '1' then
4305                  R[i] = MemA[address,4]; address = address + 4;
4306        if registers<15> == '1' then
4307            LoadWritePC(MemA[address,4]);
4308
4309        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4310        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4311#endif
4312
4313  bool success = false;
4314
4315  if (ConditionPassed(opcode)) {
4316    uint32_t n;
4317    uint32_t registers = 0;
4318    bool wback;
4319    const uint32_t addr_byte_size = GetAddressByteSize();
4320    switch (encoding) {
4321    case eEncodingA1:
4322      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4323      n = Bits32(opcode, 19, 16);
4324      registers = Bits32(opcode, 15, 0);
4325      wback = BitIsSet(opcode, 21);
4326
4327      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4328      if ((n == 15) || (BitCount(registers) < 1))
4329        return false;
4330
4331      break;
4332    default:
4333      return false;
4334    }
4335    // address = R[n] + 4;
4336
4337    int32_t offset = 0;
4338    addr_t Rn =
4339        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4340
4341    if (!success)
4342      return false;
4343
4344    addr_t address = Rn + addr_byte_size;
4345
4346    EmulateInstruction::Context context;
4347    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4348    std::optional<RegisterInfo> dwarf_reg =
4349        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4350    context.SetRegisterPlusOffset(*dwarf_reg, offset);
4351
4352    for (int i = 0; i < 14; ++i) {
4353      if (BitIsSet(registers, i)) {
4354        // R[i] = MemA[address,4]; address = address + 4;
4355
4356        context.SetRegisterPlusOffset(*dwarf_reg, offset + addr_byte_size);
4357        uint32_t data =
4358            MemARead(context, address + offset, addr_byte_size, 0, &success);
4359        if (!success)
4360          return false;
4361
4362        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4363                                   data))
4364          return false;
4365
4366        offset += addr_byte_size;
4367      }
4368    }
4369
4370    // if registers<15> == '1' then
4371    //     LoadWritePC(MemA[address,4]);
4372    if (BitIsSet(registers, 15)) {
4373      context.SetRegisterPlusOffset(*dwarf_reg, offset);
4374      uint32_t data =
4375          MemARead(context, address + offset, addr_byte_size, 0, &success);
4376      if (!success)
4377        return false;
4378      // In ARMv5T and above, this is an interworking branch.
4379      if (!LoadWritePC(context, data))
4380        return false;
4381    }
4382
4383    // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4384    if (wback && BitIsClear(registers, n)) {
4385
4386      offset = addr_byte_size * BitCount(registers);
4387      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4388      context.SetImmediateSigned(offset);
4389      addr_t addr = Rn + offset;
4390      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4391                                 addr))
4392        return false;
4393    }
4394
4395    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4396    // possible for encoding A1
4397    if (wback && BitIsSet(registers, n))
4398      return WriteBits32Unknown(n);
4399  }
4400  return true;
4401}
4402
4403// Load Register (immediate) calculates an address from a base register value
4404// and an immediate offset, loads a word from memory, and writes to a register.
4405// LDR (immediate, Thumb)
4406bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4407                                              const ARMEncoding encoding) {
4408#if 0
4409    // ARM pseudo code...
4410    if (ConditionPassed())
4411    {
4412        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4413        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4414        address = if index then offset_addr else R[n];
4415        data = MemU[address,4];
4416        if wback then R[n] = offset_addr;
4417        if t == 15 then
4418            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4419        elsif UnalignedSupport() || address<1:0> = '00' then
4420            R[t] = data;
4421        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4422    }
4423#endif
4424
4425  bool success = false;
4426
4427  if (ConditionPassed(opcode)) {
4428    uint32_t Rt;        // the destination register
4429    uint32_t Rn;        // the base register
4430    uint32_t imm32;     // the immediate offset used to form the address
4431    addr_t offset_addr; // the offset address
4432    addr_t address;     // the calculated address
4433    uint32_t data;      // the literal data value from memory load
4434    bool add, index, wback;
4435    switch (encoding) {
4436    case eEncodingT1:
4437      Rt = Bits32(opcode, 2, 0);
4438      Rn = Bits32(opcode, 5, 3);
4439      imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4440      // index = TRUE; add = TRUE; wback = FALSE
4441      add = true;
4442      index = true;
4443      wback = false;
4444
4445      break;
4446
4447    case eEncodingT2:
4448      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4449      Rt = Bits32(opcode, 10, 8);
4450      Rn = 13;
4451      imm32 = Bits32(opcode, 7, 0) << 2;
4452
4453      // index = TRUE; add = TRUE; wback = FALSE;
4454      index = true;
4455      add = true;
4456      wback = false;
4457
4458      break;
4459
4460    case eEncodingT3:
4461      // if Rn == '1111' then SEE LDR (literal);
4462      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4463      Rt = Bits32(opcode, 15, 12);
4464      Rn = Bits32(opcode, 19, 16);
4465      imm32 = Bits32(opcode, 11, 0);
4466
4467      // index = TRUE; add = TRUE; wback = FALSE;
4468      index = true;
4469      add = true;
4470      wback = false;
4471
4472      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4473      if ((Rt == 15) && InITBlock() && !LastInITBlock())
4474        return false;
4475
4476      break;
4477
4478    case eEncodingT4:
4479      // if Rn == '1111' then SEE LDR (literal);
4480      // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4481      // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4482      // '00000100' then SEE POP;
4483      // if P == '0' && W == '0' then UNDEFINED;
4484      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4485        return false;
4486
4487      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4488      Rt = Bits32(opcode, 15, 12);
4489      Rn = Bits32(opcode, 19, 16);
4490      imm32 = Bits32(opcode, 7, 0);
4491
4492      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4493      index = BitIsSet(opcode, 10);
4494      add = BitIsSet(opcode, 9);
4495      wback = BitIsSet(opcode, 8);
4496
4497      // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4498      // then UNPREDICTABLE;
4499      if ((wback && (Rn == Rt)) ||
4500          ((Rt == 15) && InITBlock() && !LastInITBlock()))
4501        return false;
4502
4503      break;
4504
4505    default:
4506      return false;
4507    }
4508    uint32_t base = ReadCoreReg(Rn, &success);
4509    if (!success)
4510      return false;
4511    if (add)
4512      offset_addr = base + imm32;
4513    else
4514      offset_addr = base - imm32;
4515
4516    address = (index ? offset_addr : base);
4517
4518    std::optional<RegisterInfo> base_reg =
4519        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn);
4520    if (wback) {
4521      EmulateInstruction::Context ctx;
4522      if (Rn == 13) {
4523        ctx.type = eContextAdjustStackPointer;
4524        ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4525      } else if (Rn == GetFramePointerRegisterNumber()) {
4526        ctx.type = eContextSetFramePointer;
4527        ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4528      } else {
4529        ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4530        ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4531      }
4532
4533      if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4534                                 offset_addr))
4535        return false;
4536    }
4537
4538    // Prepare to write to the Rt register.
4539    EmulateInstruction::Context context;
4540    context.type = EmulateInstruction::eContextRegisterLoad;
4541    context.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4542
4543    // Read memory from the address.
4544    data = MemURead(context, address, 4, 0, &success);
4545    if (!success)
4546      return false;
4547
4548    if (Rt == 15) {
4549      if (Bits32(address, 1, 0) == 0) {
4550        if (!LoadWritePC(context, data))
4551          return false;
4552      } else
4553        return false;
4554    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4555      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4556                                 data))
4557        return false;
4558    } else
4559      WriteBits32Unknown(Rt);
4560  }
4561  return true;
4562}
4563
4564// STM (Store Multiple Increment After) stores multiple registers to consecutive
4565// memory locations using an address
4566// from a base register.  The consecutive memory locations start at this
4567// address, and the address just above the last of those locations can
4568// optionally be written back to the base register.
4569bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4570                                       const ARMEncoding encoding) {
4571#if 0
4572    if ConditionPassed() then
4573        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4574        address = R[n];
4575
4576        for i = 0 to 14
4577            if registers<i> == '1' then
4578                if i == n && wback && i != LowestSetBit(registers) then
4579                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4580                else
4581                    MemA[address,4] = R[i];
4582                address = address + 4;
4583
4584        if registers<15> == '1' then // Only possible for encoding A1
4585            MemA[address,4] = PCStoreValue();
4586        if wback then R[n] = R[n] + 4*BitCount(registers);
4587#endif
4588
4589  bool success = false;
4590
4591  if (ConditionPassed(opcode)) {
4592    uint32_t n;
4593    uint32_t registers = 0;
4594    bool wback;
4595    const uint32_t addr_byte_size = GetAddressByteSize();
4596
4597    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4598    switch (encoding) {
4599    case eEncodingT1:
4600      // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4601      n = Bits32(opcode, 10, 8);
4602      registers = Bits32(opcode, 7, 0);
4603      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4604      wback = true;
4605
4606      // if BitCount(registers) < 1 then UNPREDICTABLE;
4607      if (BitCount(registers) < 1)
4608        return false;
4609
4610      break;
4611
4612    case eEncodingT2:
4613      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4614      n = Bits32(opcode, 19, 16);
4615      registers = Bits32(opcode, 15, 0);
4616      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4617      wback = BitIsSet(opcode, 21);
4618
4619      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4620      if ((n == 15) || (BitCount(registers) < 2))
4621        return false;
4622
4623      // if wback && registers<n> == '1' then UNPREDICTABLE;
4624      if (wback && BitIsSet(registers, n))
4625        return false;
4626
4627      break;
4628
4629    case eEncodingA1:
4630      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4631      n = Bits32(opcode, 19, 16);
4632      registers = Bits32(opcode, 15, 0);
4633      wback = BitIsSet(opcode, 21);
4634
4635      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4636      if ((n == 15) || (BitCount(registers) < 1))
4637        return false;
4638
4639      break;
4640
4641    default:
4642      return false;
4643    }
4644
4645    // address = R[n];
4646    int32_t offset = 0;
4647    const addr_t address =
4648        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4649    if (!success)
4650      return false;
4651
4652    EmulateInstruction::Context context;
4653    context.type = EmulateInstruction::eContextRegisterStore;
4654    std::optional<RegisterInfo> base_reg =
4655        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4656
4657    // for i = 0 to 14
4658    uint32_t lowest_set_bit = 14;
4659    for (uint32_t i = 0; i < 14; ++i) {
4660      // if registers<i> == '1' then
4661      if (BitIsSet(registers, i)) {
4662        if (i < lowest_set_bit)
4663          lowest_set_bit = i;
4664        // if i == n && wback && i != LowestSetBit(registers) then
4665        if ((i == n) && wback && (i != lowest_set_bit))
4666          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4667          // T1 and A1
4668          WriteBits32UnknownToMemory(address + offset);
4669        else {
4670          // MemA[address,4] = R[i];
4671          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4672                                               0, &success);
4673          if (!success)
4674            return false;
4675
4676          std::optional<RegisterInfo> data_reg =
4677              GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4678          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
4679          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4680            return false;
4681        }
4682
4683        // address = address + 4;
4684        offset += addr_byte_size;
4685      }
4686    }
4687
4688    // if registers<15> == '1' then // Only possible for encoding A1
4689    //     MemA[address,4] = PCStoreValue();
4690    if (BitIsSet(registers, 15)) {
4691      std::optional<RegisterInfo> pc_reg =
4692          GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4693      context.SetRegisterPlusOffset(*pc_reg, 8);
4694      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4695      if (!success)
4696        return false;
4697
4698      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4699        return false;
4700    }
4701
4702    // if wback then R[n] = R[n] + 4*BitCount(registers);
4703    if (wback) {
4704      offset = addr_byte_size * BitCount(registers);
4705      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4706      context.SetImmediateSigned(offset);
4707      addr_t data = address + offset;
4708      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4709                                 data))
4710        return false;
4711    }
4712  }
4713  return true;
4714}
4715
4716// STMDA (Store Multiple Decrement After) stores multiple registers to
4717// consecutive memory locations using an address from a base register.  The
4718// consecutive memory locations end at this address, and the address just below
4719// the lowest of those locations can optionally be written back to the base
4720// register.
4721bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4722                                         const ARMEncoding encoding) {
4723#if 0
4724    if ConditionPassed() then
4725        EncodingSpecificOperations();
4726        address = R[n] - 4*BitCount(registers) + 4;
4727
4728        for i = 0 to 14
4729            if registers<i> == '1' then
4730                if i == n && wback && i != LowestSetBit(registers) then
4731                    MemA[address,4] = bits(32) UNKNOWN;
4732                else
4733                    MemA[address,4] = R[i];
4734                address = address + 4;
4735
4736        if registers<15> == '1' then
4737            MemA[address,4] = PCStoreValue();
4738
4739        if wback then R[n] = R[n] - 4*BitCount(registers);
4740#endif
4741
4742  bool success = false;
4743
4744  if (ConditionPassed(opcode)) {
4745    uint32_t n;
4746    uint32_t registers = 0;
4747    bool wback;
4748    const uint32_t addr_byte_size = GetAddressByteSize();
4749
4750    // EncodingSpecificOperations();
4751    switch (encoding) {
4752    case eEncodingA1:
4753      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4754      n = Bits32(opcode, 19, 16);
4755      registers = Bits32(opcode, 15, 0);
4756      wback = BitIsSet(opcode, 21);
4757
4758      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4759      if ((n == 15) || (BitCount(registers) < 1))
4760        return false;
4761      break;
4762    default:
4763      return false;
4764    }
4765
4766    // address = R[n] - 4*BitCount(registers) + 4;
4767    int32_t offset = 0;
4768    addr_t Rn = ReadCoreReg(n, &success);
4769    if (!success)
4770      return false;
4771
4772    addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4773
4774    EmulateInstruction::Context context;
4775    context.type = EmulateInstruction::eContextRegisterStore;
4776    std::optional<RegisterInfo> base_reg =
4777        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4778
4779    // for i = 0 to 14
4780    uint32_t lowest_bit_set = 14;
4781    for (uint32_t i = 0; i < 14; ++i) {
4782      // if registers<i> == '1' then
4783      if (BitIsSet(registers, i)) {
4784        if (i < lowest_bit_set)
4785          lowest_bit_set = i;
4786        // if i == n && wback && i != LowestSetBit(registers) then
4787        if ((i == n) && wback && (i != lowest_bit_set))
4788          // MemA[address,4] = bits(32) UNKNOWN;
4789          WriteBits32UnknownToMemory(address + offset);
4790        else {
4791          // MemA[address,4] = R[i];
4792          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4793                                               0, &success);
4794          if (!success)
4795            return false;
4796
4797          std::optional<RegisterInfo> data_reg =
4798              GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4799          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4800                                                  Rn - (address + offset));
4801          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4802            return false;
4803        }
4804
4805        // address = address + 4;
4806        offset += addr_byte_size;
4807      }
4808    }
4809
4810    // if registers<15> == '1' then
4811    //    MemA[address,4] = PCStoreValue();
4812    if (BitIsSet(registers, 15)) {
4813      std::optional<RegisterInfo> pc_reg =
4814          GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4815      context.SetRegisterPlusOffset(*pc_reg, 8);
4816      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4817      if (!success)
4818        return false;
4819
4820      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4821        return false;
4822    }
4823
4824    // if wback then R[n] = R[n] - 4*BitCount(registers);
4825    if (wback) {
4826      offset = (addr_byte_size * BitCount(registers)) * -1;
4827      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4828      context.SetImmediateSigned(offset);
4829      addr_t data = Rn + offset;
4830      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4831                                 data))
4832        return false;
4833    }
4834  }
4835  return true;
4836}
4837
4838// STMDB (Store Multiple Decrement Before) stores multiple registers to
4839// consecutive memory locations using an address from a base register.  The
4840// consecutive memory locations end just below this address, and the address of
4841// the first of those locations can optionally be written back to the base
4842// register.
4843bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4844                                         const ARMEncoding encoding) {
4845#if 0
4846    if ConditionPassed() then
4847        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4848        address = R[n] - 4*BitCount(registers);
4849
4850        for i = 0 to 14
4851            if registers<i> == '1' then
4852                if i == n && wback && i != LowestSetBit(registers) then
4853                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4854                else
4855                    MemA[address,4] = R[i];
4856                address = address + 4;
4857
4858        if registers<15> == '1' then // Only possible for encoding A1
4859            MemA[address,4] = PCStoreValue();
4860
4861        if wback then R[n] = R[n] - 4*BitCount(registers);
4862#endif
4863
4864  bool success = false;
4865
4866  if (ConditionPassed(opcode)) {
4867    uint32_t n;
4868    uint32_t registers = 0;
4869    bool wback;
4870    const uint32_t addr_byte_size = GetAddressByteSize();
4871
4872    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4873    switch (encoding) {
4874    case eEncodingT1:
4875      // if W == '1' && Rn == '1101' then SEE PUSH;
4876      if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4877        // See PUSH
4878      }
4879      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4880      n = Bits32(opcode, 19, 16);
4881      registers = Bits32(opcode, 15, 0);
4882      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4883      wback = BitIsSet(opcode, 21);
4884      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4885      if ((n == 15) || BitCount(registers) < 2)
4886        return false;
4887      // if wback && registers<n> == '1' then UNPREDICTABLE;
4888      if (wback && BitIsSet(registers, n))
4889        return false;
4890      break;
4891
4892    case eEncodingA1:
4893      // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4894      // PUSH;
4895      if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4896          BitCount(Bits32(opcode, 15, 0)) >= 2) {
4897        // See Push
4898      }
4899      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4900      n = Bits32(opcode, 19, 16);
4901      registers = Bits32(opcode, 15, 0);
4902      wback = BitIsSet(opcode, 21);
4903      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4904      if ((n == 15) || BitCount(registers) < 1)
4905        return false;
4906      break;
4907
4908    default:
4909      return false;
4910    }
4911
4912    // address = R[n] - 4*BitCount(registers);
4913
4914    int32_t offset = 0;
4915    addr_t Rn =
4916        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4917    if (!success)
4918      return false;
4919
4920    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4921
4922    EmulateInstruction::Context context;
4923    context.type = EmulateInstruction::eContextRegisterStore;
4924    std::optional<RegisterInfo> base_reg =
4925        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4926
4927    // for i = 0 to 14
4928    uint32_t lowest_set_bit = 14;
4929    for (uint32_t i = 0; i < 14; ++i) {
4930      // if registers<i> == '1' then
4931      if (BitIsSet(registers, i)) {
4932        if (i < lowest_set_bit)
4933          lowest_set_bit = i;
4934        // if i == n && wback && i != LowestSetBit(registers) then
4935        if ((i == n) && wback && (i != lowest_set_bit))
4936          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4937          // A1
4938          WriteBits32UnknownToMemory(address + offset);
4939        else {
4940          // MemA[address,4] = R[i];
4941          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4942                                               0, &success);
4943          if (!success)
4944            return false;
4945
4946          std::optional<RegisterInfo> data_reg =
4947              GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4948          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4949                                                  Rn - (address + offset));
4950          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4951            return false;
4952        }
4953
4954        // address = address + 4;
4955        offset += addr_byte_size;
4956      }
4957    }
4958
4959    // if registers<15> == '1' then // Only possible for encoding A1
4960    //     MemA[address,4] = PCStoreValue();
4961    if (BitIsSet(registers, 15)) {
4962      std::optional<RegisterInfo> pc_reg =
4963          GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4964      context.SetRegisterPlusOffset(*pc_reg, 8);
4965      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4966      if (!success)
4967        return false;
4968
4969      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4970        return false;
4971    }
4972
4973    // if wback then R[n] = R[n] - 4*BitCount(registers);
4974    if (wback) {
4975      offset = (addr_byte_size * BitCount(registers)) * -1;
4976      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4977      context.SetImmediateSigned(offset);
4978      addr_t data = Rn + offset;
4979      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4980                                 data))
4981        return false;
4982    }
4983  }
4984  return true;
4985}
4986
4987// STMIB (Store Multiple Increment Before) stores multiple registers to
4988// consecutive memory locations using an address from a base register.  The
4989// consecutive memory locations start just above this address, and the address
4990// of the last of those locations can optionally be written back to the base
4991// register.
4992bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
4993                                         const ARMEncoding encoding) {
4994#if 0
4995    if ConditionPassed() then
4996        EncodingSpecificOperations();
4997        address = R[n] + 4;
4998
4999        for i = 0 to 14
5000            if registers<i> == '1' then
5001                if i == n && wback && i != LowestSetBit(registers) then
5002                    MemA[address,4] = bits(32) UNKNOWN;
5003                else
5004                    MemA[address,4] = R[i];
5005                address = address + 4;
5006
5007        if registers<15> == '1' then
5008            MemA[address,4] = PCStoreValue();
5009
5010        if wback then R[n] = R[n] + 4*BitCount(registers);
5011#endif
5012
5013  bool success = false;
5014
5015  if (ConditionPassed(opcode)) {
5016    uint32_t n;
5017    uint32_t registers = 0;
5018    bool wback;
5019    const uint32_t addr_byte_size = GetAddressByteSize();
5020
5021    // EncodingSpecificOperations();
5022    switch (encoding) {
5023    case eEncodingA1:
5024      // n = UInt(Rn); registers = register_list; wback = (W == '1');
5025      n = Bits32(opcode, 19, 16);
5026      registers = Bits32(opcode, 15, 0);
5027      wback = BitIsSet(opcode, 21);
5028
5029      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5030      if ((n == 15) && (BitCount(registers) < 1))
5031        return false;
5032      break;
5033    default:
5034      return false;
5035    }
5036    // address = R[n] + 4;
5037
5038    int32_t offset = 0;
5039    addr_t Rn = ReadCoreReg(n, &success);
5040    if (!success)
5041      return false;
5042
5043    addr_t address = Rn + addr_byte_size;
5044
5045    EmulateInstruction::Context context;
5046    context.type = EmulateInstruction::eContextRegisterStore;
5047    std::optional<RegisterInfo> base_reg =
5048        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5049
5050    uint32_t lowest_set_bit = 14;
5051    // for i = 0 to 14
5052    for (uint32_t i = 0; i < 14; ++i) {
5053      // if registers<i> == '1' then
5054      if (BitIsSet(registers, i)) {
5055        if (i < lowest_set_bit)
5056          lowest_set_bit = i;
5057        // if i == n && wback && i != LowestSetBit(registers) then
5058        if ((i == n) && wback && (i != lowest_set_bit))
5059          // MemA[address,4] = bits(32) UNKNOWN;
5060          WriteBits32UnknownToMemory(address + offset);
5061        // else
5062        else {
5063          // MemA[address,4] = R[i];
5064          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5065                                               0, &success);
5066          if (!success)
5067            return false;
5068
5069          std::optional<RegisterInfo> data_reg =
5070              GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
5071          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5072                                                  offset + addr_byte_size);
5073          if (!MemAWrite(context, address + offset, data, addr_byte_size))
5074            return false;
5075        }
5076
5077        // address = address + 4;
5078        offset += addr_byte_size;
5079      }
5080    }
5081
5082    // if registers<15> == '1' then
5083    // MemA[address,4] = PCStoreValue();
5084    if (BitIsSet(registers, 15)) {
5085      std::optional<RegisterInfo> pc_reg =
5086          GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
5087      context.SetRegisterPlusOffset(*pc_reg, 8);
5088      const uint32_t pc = ReadCoreReg(PC_REG, &success);
5089      if (!success)
5090        return false;
5091
5092      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5093        return false;
5094    }
5095
5096    // if wback then R[n] = R[n] + 4*BitCount(registers);
5097    if (wback) {
5098      offset = addr_byte_size * BitCount(registers);
5099      context.type = EmulateInstruction::eContextAdjustBaseRegister;
5100      context.SetImmediateSigned(offset);
5101      addr_t data = Rn + offset;
5102      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5103                                 data))
5104        return false;
5105    }
5106  }
5107  return true;
5108}
5109
5110// STR (store immediate) calculates an address from a base register value and an
5111// immediate offset, and stores a word
5112// from a register to memory.  It can use offset, post-indexed, or pre-indexed
5113// addressing.
5114bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5115                                            const ARMEncoding encoding) {
5116#if 0
5117    if ConditionPassed() then
5118        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5119        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5120        address = if index then offset_addr else R[n];
5121        if UnalignedSupport() || address<1:0> == '00' then
5122            MemU[address,4] = R[t];
5123        else // Can only occur before ARMv7
5124            MemU[address,4] = bits(32) UNKNOWN;
5125        if wback then R[n] = offset_addr;
5126#endif
5127
5128  bool success = false;
5129
5130  if (ConditionPassed(opcode)) {
5131    const uint32_t addr_byte_size = GetAddressByteSize();
5132
5133    uint32_t t;
5134    uint32_t n;
5135    uint32_t imm32;
5136    bool index;
5137    bool add;
5138    bool wback;
5139    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5140    switch (encoding) {
5141    case eEncodingT1:
5142      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5143      t = Bits32(opcode, 2, 0);
5144      n = Bits32(opcode, 5, 3);
5145      imm32 = Bits32(opcode, 10, 6) << 2;
5146
5147      // index = TRUE; add = TRUE; wback = FALSE;
5148      index = true;
5149      add = false;
5150      wback = false;
5151      break;
5152
5153    case eEncodingT2:
5154      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5155      t = Bits32(opcode, 10, 8);
5156      n = 13;
5157      imm32 = Bits32(opcode, 7, 0) << 2;
5158
5159      // index = TRUE; add = TRUE; wback = FALSE;
5160      index = true;
5161      add = true;
5162      wback = false;
5163      break;
5164
5165    case eEncodingT3:
5166      // if Rn == '1111' then UNDEFINED;
5167      if (Bits32(opcode, 19, 16) == 15)
5168        return false;
5169
5170      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5171      t = Bits32(opcode, 15, 12);
5172      n = Bits32(opcode, 19, 16);
5173      imm32 = Bits32(opcode, 11, 0);
5174
5175      // index = TRUE; add = TRUE; wback = FALSE;
5176      index = true;
5177      add = true;
5178      wback = false;
5179
5180      // if t == 15 then UNPREDICTABLE;
5181      if (t == 15)
5182        return false;
5183      break;
5184
5185    case eEncodingT4:
5186      // if P == '1' && U == '1' && W == '0' then SEE STRT;
5187      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5188      // '00000100' then SEE PUSH;
5189      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5190      if ((Bits32(opcode, 19, 16) == 15) ||
5191          (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5192        return false;
5193
5194      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5195      t = Bits32(opcode, 15, 12);
5196      n = Bits32(opcode, 19, 16);
5197      imm32 = Bits32(opcode, 7, 0);
5198
5199      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5200      index = BitIsSet(opcode, 10);
5201      add = BitIsSet(opcode, 9);
5202      wback = BitIsSet(opcode, 8);
5203
5204      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5205      if ((t == 15) || (wback && (n == t)))
5206        return false;
5207      break;
5208
5209    default:
5210      return false;
5211    }
5212
5213    addr_t offset_addr;
5214    addr_t address;
5215
5216    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5217    uint32_t base_address = ReadCoreReg(n, &success);
5218    if (!success)
5219      return false;
5220
5221    if (add)
5222      offset_addr = base_address + imm32;
5223    else
5224      offset_addr = base_address - imm32;
5225
5226    // address = if index then offset_addr else R[n];
5227    if (index)
5228      address = offset_addr;
5229    else
5230      address = base_address;
5231
5232    EmulateInstruction::Context context;
5233    if (n == 13)
5234      context.type = eContextPushRegisterOnStack;
5235    else
5236      context.type = eContextRegisterStore;
5237
5238    std::optional<RegisterInfo> base_reg =
5239        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5240
5241    // if UnalignedSupport() || address<1:0> == '00' then
5242    if (UnalignedSupport() ||
5243        (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5244      // MemU[address,4] = R[t];
5245      uint32_t data =
5246          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5247      if (!success)
5248        return false;
5249
5250      std::optional<RegisterInfo> data_reg =
5251          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5252      int32_t offset = address - base_address;
5253      context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
5254      if (!MemUWrite(context, address, data, addr_byte_size))
5255        return false;
5256    } else {
5257      // MemU[address,4] = bits(32) UNKNOWN;
5258      WriteBits32UnknownToMemory(address);
5259    }
5260
5261    // if wback then R[n] = offset_addr;
5262    if (wback) {
5263      if (n == 13)
5264        context.type = eContextAdjustStackPointer;
5265      else
5266        context.type = eContextAdjustBaseRegister;
5267      context.SetAddress(offset_addr);
5268
5269      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5270                                 offset_addr))
5271        return false;
5272    }
5273  }
5274  return true;
5275}
5276
5277// STR (Store Register) calculates an address from a base register value and an
5278// offset register value, stores a
5279// word from a register to memory.   The offset register value can optionally
5280// be shifted.
5281bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5282                                               const ARMEncoding encoding) {
5283#if 0
5284    if ConditionPassed() then
5285        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5286        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5287        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5288        address = if index then offset_addr else R[n];
5289        if t == 15 then // Only possible for encoding A1
5290            data = PCStoreValue();
5291        else
5292            data = R[t];
5293        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5294            MemU[address,4] = data;
5295        else // Can only occur before ARMv7
5296            MemU[address,4] = bits(32) UNKNOWN;
5297        if wback then R[n] = offset_addr;
5298#endif
5299
5300  bool success = false;
5301
5302  if (ConditionPassed(opcode)) {
5303    const uint32_t addr_byte_size = GetAddressByteSize();
5304
5305    uint32_t t;
5306    uint32_t n;
5307    uint32_t m;
5308    ARM_ShifterType shift_t;
5309    uint32_t shift_n;
5310    bool index;
5311    bool add;
5312    bool wback;
5313
5314    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5315    switch (encoding) {
5316    case eEncodingT1:
5317      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5318      // in ThumbEE";
5319      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5320      t = Bits32(opcode, 2, 0);
5321      n = Bits32(opcode, 5, 3);
5322      m = Bits32(opcode, 8, 6);
5323
5324      // index = TRUE; add = TRUE; wback = FALSE;
5325      index = true;
5326      add = true;
5327      wback = false;
5328
5329      // (shift_t, shift_n) = (SRType_LSL, 0);
5330      shift_t = SRType_LSL;
5331      shift_n = 0;
5332      break;
5333
5334    case eEncodingT2:
5335      // if Rn == '1111' then UNDEFINED;
5336      if (Bits32(opcode, 19, 16) == 15)
5337        return false;
5338
5339      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5340      t = Bits32(opcode, 15, 12);
5341      n = Bits32(opcode, 19, 16);
5342      m = Bits32(opcode, 3, 0);
5343
5344      // index = TRUE; add = TRUE; wback = FALSE;
5345      index = true;
5346      add = true;
5347      wback = false;
5348
5349      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5350      shift_t = SRType_LSL;
5351      shift_n = Bits32(opcode, 5, 4);
5352
5353      // if t == 15 || BadReg(m) then UNPREDICTABLE;
5354      if ((t == 15) || (BadReg(m)))
5355        return false;
5356      break;
5357
5358    case eEncodingA1: {
5359      // if P == '0' && W == '1' then SEE STRT;
5360      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5361      t = Bits32(opcode, 15, 12);
5362      n = Bits32(opcode, 19, 16);
5363      m = Bits32(opcode, 3, 0);
5364
5365      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5366      // (W == '1');
5367      index = BitIsSet(opcode, 24);
5368      add = BitIsSet(opcode, 23);
5369      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5370
5371      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5372      uint32_t typ = Bits32(opcode, 6, 5);
5373      uint32_t imm5 = Bits32(opcode, 11, 7);
5374      shift_n = DecodeImmShift(typ, imm5, shift_t);
5375
5376      // if m == 15 then UNPREDICTABLE;
5377      if (m == 15)
5378        return false;
5379
5380      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5381      if (wback && ((n == 15) || (n == t)))
5382        return false;
5383
5384      break;
5385    }
5386    default:
5387      return false;
5388    }
5389
5390    addr_t offset_addr;
5391    addr_t address;
5392    int32_t offset = 0;
5393
5394    addr_t base_address =
5395        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5396    if (!success)
5397      return false;
5398
5399    uint32_t Rm_data =
5400        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5401    if (!success)
5402      return false;
5403
5404    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5405    offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5406    if (!success)
5407      return false;
5408
5409    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5410    if (add)
5411      offset_addr = base_address + offset;
5412    else
5413      offset_addr = base_address - offset;
5414
5415    // address = if index then offset_addr else R[n];
5416    if (index)
5417      address = offset_addr;
5418    else
5419      address = base_address;
5420
5421    uint32_t data;
5422    // if t == 15 then // Only possible for encoding A1
5423    if (t == 15)
5424      // data = PCStoreValue();
5425      data = ReadCoreReg(PC_REG, &success);
5426    else
5427      // data = R[t];
5428      data =
5429          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5430
5431    if (!success)
5432      return false;
5433
5434    EmulateInstruction::Context context;
5435    context.type = eContextRegisterStore;
5436
5437    // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5438    // InstrSet_ARM then
5439    if (UnalignedSupport() ||
5440        (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5441        CurrentInstrSet() == eModeARM) {
5442      // MemU[address,4] = data;
5443
5444      std::optional<RegisterInfo> base_reg =
5445          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5446      std::optional<RegisterInfo> data_reg =
5447          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5448
5449      context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5450                                              address - base_address);
5451      if (!MemUWrite(context, address, data, addr_byte_size))
5452        return false;
5453
5454    } else
5455      // MemU[address,4] = bits(32) UNKNOWN;
5456      WriteBits32UnknownToMemory(address);
5457
5458    // if wback then R[n] = offset_addr;
5459    if (wback) {
5460      context.type = eContextRegisterLoad;
5461      context.SetAddress(offset_addr);
5462      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5463                                 offset_addr))
5464        return false;
5465    }
5466  }
5467  return true;
5468}
5469
5470bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5471                                             const ARMEncoding encoding) {
5472#if 0
5473    if ConditionPassed() then
5474        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5475        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5476        address = if index then offset_addr else R[n];
5477        MemU[address,1] = R[t]<7:0>;
5478        if wback then R[n] = offset_addr;
5479#endif
5480
5481  bool success = false;
5482
5483  if (ConditionPassed(opcode)) {
5484    uint32_t t;
5485    uint32_t n;
5486    uint32_t imm32;
5487    bool index;
5488    bool add;
5489    bool wback;
5490    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5491    switch (encoding) {
5492    case eEncodingT1:
5493      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5494      t = Bits32(opcode, 2, 0);
5495      n = Bits32(opcode, 5, 3);
5496      imm32 = Bits32(opcode, 10, 6);
5497
5498      // index = TRUE; add = TRUE; wback = FALSE;
5499      index = true;
5500      add = true;
5501      wback = false;
5502      break;
5503
5504    case eEncodingT2:
5505      // if Rn == '1111' then UNDEFINED;
5506      if (Bits32(opcode, 19, 16) == 15)
5507        return false;
5508
5509      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5510      t = Bits32(opcode, 15, 12);
5511      n = Bits32(opcode, 19, 16);
5512      imm32 = Bits32(opcode, 11, 0);
5513
5514      // index = TRUE; add = TRUE; wback = FALSE;
5515      index = true;
5516      add = true;
5517      wback = false;
5518
5519      // if BadReg(t) then UNPREDICTABLE;
5520      if (BadReg(t))
5521        return false;
5522      break;
5523
5524    case eEncodingT3:
5525      // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5526      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5527      if (Bits32(opcode, 19, 16) == 15)
5528        return false;
5529
5530      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5531      t = Bits32(opcode, 15, 12);
5532      n = Bits32(opcode, 19, 16);
5533      imm32 = Bits32(opcode, 7, 0);
5534
5535      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5536      index = BitIsSet(opcode, 10);
5537      add = BitIsSet(opcode, 9);
5538      wback = BitIsSet(opcode, 8);
5539
5540      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5541      if ((BadReg(t)) || (wback && (n == t)))
5542        return false;
5543      break;
5544
5545    default:
5546      return false;
5547    }
5548
5549    addr_t offset_addr;
5550    addr_t address;
5551    addr_t base_address =
5552        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5553    if (!success)
5554      return false;
5555
5556    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5557    if (add)
5558      offset_addr = base_address + imm32;
5559    else
5560      offset_addr = base_address - imm32;
5561
5562    // address = if index then offset_addr else R[n];
5563    if (index)
5564      address = offset_addr;
5565    else
5566      address = base_address;
5567
5568    // MemU[address,1] = R[t]<7:0>
5569    std::optional<RegisterInfo> base_reg =
5570        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5571    std::optional<RegisterInfo> data_reg =
5572        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5573
5574    EmulateInstruction::Context context;
5575    context.type = eContextRegisterStore;
5576    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5577                                            address - base_address);
5578
5579    uint32_t data =
5580        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5581    if (!success)
5582      return false;
5583
5584    data = Bits32(data, 7, 0);
5585
5586    if (!MemUWrite(context, address, data, 1))
5587      return false;
5588
5589    // if wback then R[n] = offset_addr;
5590    if (wback) {
5591      context.type = eContextRegisterLoad;
5592      context.SetAddress(offset_addr);
5593      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5594                                 offset_addr))
5595        return false;
5596    }
5597  }
5598
5599  return true;
5600}
5601
5602// STRH (register) calculates an address from a base register value and an
5603// offset register value, and stores a
5604// halfword from a register to memory.  The offset register value can be
5605// shifted left by 0, 1, 2, or 3 bits.
5606bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5607                                                const ARMEncoding encoding) {
5608#if 0
5609    if ConditionPassed() then
5610        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5611        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5612        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5613        address = if index then offset_addr else R[n];
5614        if UnalignedSupport() || address<0> == '0' then
5615            MemU[address,2] = R[t]<15:0>;
5616        else // Can only occur before ARMv7
5617            MemU[address,2] = bits(16) UNKNOWN;
5618        if wback then R[n] = offset_addr;
5619#endif
5620
5621  bool success = false;
5622
5623  if (ConditionPassed(opcode)) {
5624    uint32_t t;
5625    uint32_t n;
5626    uint32_t m;
5627    bool index;
5628    bool add;
5629    bool wback;
5630    ARM_ShifterType shift_t;
5631    uint32_t shift_n;
5632
5633    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5634    switch (encoding) {
5635    case eEncodingT1:
5636      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5637      // in ThumbEE";
5638      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5639      t = Bits32(opcode, 2, 0);
5640      n = Bits32(opcode, 5, 3);
5641      m = Bits32(opcode, 8, 6);
5642
5643      // index = TRUE; add = TRUE; wback = FALSE;
5644      index = true;
5645      add = true;
5646      wback = false;
5647
5648      // (shift_t, shift_n) = (SRType_LSL, 0);
5649      shift_t = SRType_LSL;
5650      shift_n = 0;
5651
5652      break;
5653
5654    case eEncodingT2:
5655      // if Rn == '1111' then UNDEFINED;
5656      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5657      t = Bits32(opcode, 15, 12);
5658      n = Bits32(opcode, 19, 16);
5659      m = Bits32(opcode, 3, 0);
5660      if (n == 15)
5661        return false;
5662
5663      // index = TRUE; add = TRUE; wback = FALSE;
5664      index = true;
5665      add = true;
5666      wback = false;
5667
5668      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5669      shift_t = SRType_LSL;
5670      shift_n = Bits32(opcode, 5, 4);
5671
5672      // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5673      if (BadReg(t) || BadReg(m))
5674        return false;
5675
5676      break;
5677
5678    case eEncodingA1:
5679      // if P == '0' && W == '1' then SEE STRHT;
5680      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5681      t = Bits32(opcode, 15, 12);
5682      n = Bits32(opcode, 19, 16);
5683      m = Bits32(opcode, 3, 0);
5684
5685      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5686      // (W == '1');
5687      index = BitIsSet(opcode, 24);
5688      add = BitIsSet(opcode, 23);
5689      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5690
5691      // (shift_t, shift_n) = (SRType_LSL, 0);
5692      shift_t = SRType_LSL;
5693      shift_n = 0;
5694
5695      // if t == 15 || m == 15 then UNPREDICTABLE;
5696      if ((t == 15) || (m == 15))
5697        return false;
5698
5699      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5700      if (wback && ((n == 15) || (n == t)))
5701        return false;
5702
5703      break;
5704
5705    default:
5706      return false;
5707    }
5708
5709    uint32_t Rm = ReadCoreReg(m, &success);
5710    if (!success)
5711      return false;
5712
5713    uint32_t Rn = ReadCoreReg(n, &success);
5714    if (!success)
5715      return false;
5716
5717    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5718    uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5719    if (!success)
5720      return false;
5721
5722    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5723    addr_t offset_addr;
5724    if (add)
5725      offset_addr = Rn + offset;
5726    else
5727      offset_addr = Rn - offset;
5728
5729    // address = if index then offset_addr else R[n];
5730    addr_t address;
5731    if (index)
5732      address = offset_addr;
5733    else
5734      address = Rn;
5735
5736    EmulateInstruction::Context context;
5737    context.type = eContextRegisterStore;
5738
5739    // if UnalignedSupport() || address<0> == '0' then
5740    if (UnalignedSupport() || BitIsClear(address, 0)) {
5741      // MemU[address,2] = R[t]<15:0>;
5742      uint32_t Rt = ReadCoreReg(t, &success);
5743      if (!success)
5744        return false;
5745
5746      EmulateInstruction::Context context;
5747      context.type = eContextRegisterStore;
5748      std::optional<RegisterInfo> base_reg =
5749          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5750      std::optional<RegisterInfo> offset_reg =
5751          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
5752      std::optional<RegisterInfo> data_reg =
5753          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5754      context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
5755                                                      *data_reg);
5756
5757      if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5758        return false;
5759    } else // Can only occur before ARMv7
5760    {
5761      // MemU[address,2] = bits(16) UNKNOWN;
5762    }
5763
5764    // if wback then R[n] = offset_addr;
5765    if (wback) {
5766      context.type = eContextAdjustBaseRegister;
5767      context.SetAddress(offset_addr);
5768      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5769                                 offset_addr))
5770        return false;
5771    }
5772  }
5773
5774  return true;
5775}
5776
5777// Add with Carry (immediate) adds an immediate value and the carry flag value
5778// to a register value, and writes the result to the destination register.  It
5779// can optionally update the condition flags based on the result.
5780bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5781                                          const ARMEncoding encoding) {
5782#if 0
5783    // ARM pseudo code...
5784    if ConditionPassed() then
5785        EncodingSpecificOperations();
5786        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5787        if d == 15 then         // Can only occur for ARM encoding
5788            ALUWritePC(result); // setflags is always FALSE here
5789        else
5790            R[d] = result;
5791            if setflags then
5792                APSR.N = result<31>;
5793                APSR.Z = IsZeroBit(result);
5794                APSR.C = carry;
5795                APSR.V = overflow;
5796#endif
5797
5798  bool success = false;
5799
5800  if (ConditionPassed(opcode)) {
5801    uint32_t Rd, Rn;
5802    uint32_t
5803        imm32; // the immediate value to be added to the value obtained from Rn
5804    bool setflags;
5805    switch (encoding) {
5806    case eEncodingT1:
5807      Rd = Bits32(opcode, 11, 8);
5808      Rn = Bits32(opcode, 19, 16);
5809      setflags = BitIsSet(opcode, 20);
5810      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5811      if (BadReg(Rd) || BadReg(Rn))
5812        return false;
5813      break;
5814    case eEncodingA1:
5815      Rd = Bits32(opcode, 15, 12);
5816      Rn = Bits32(opcode, 19, 16);
5817      setflags = BitIsSet(opcode, 20);
5818      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5819
5820      if (Rd == 15 && setflags)
5821        return EmulateSUBSPcLrEtc(opcode, encoding);
5822      break;
5823    default:
5824      return false;
5825    }
5826
5827    // Read the first operand.
5828    int32_t val1 = ReadCoreReg(Rn, &success);
5829    if (!success)
5830      return false;
5831
5832    AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5833
5834    EmulateInstruction::Context context;
5835    context.type = EmulateInstruction::eContextImmediate;
5836    context.SetNoArgs();
5837
5838    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5839                                   res.carry_out, res.overflow))
5840      return false;
5841  }
5842  return true;
5843}
5844
5845// Add with Carry (register) adds a register value, the carry flag value, and
5846// an optionally-shifted register value, and writes the result to the
5847// destination register.  It can optionally update the condition flags based on
5848// the result.
5849bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5850                                          const ARMEncoding encoding) {
5851#if 0
5852    // ARM pseudo code...
5853    if ConditionPassed() then
5854        EncodingSpecificOperations();
5855        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5856        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5857        if d == 15 then         // Can only occur for ARM encoding
5858            ALUWritePC(result); // setflags is always FALSE here
5859        else
5860            R[d] = result;
5861            if setflags then
5862                APSR.N = result<31>;
5863                APSR.Z = IsZeroBit(result);
5864                APSR.C = carry;
5865                APSR.V = overflow;
5866#endif
5867
5868  bool success = false;
5869
5870  if (ConditionPassed(opcode)) {
5871    uint32_t Rd, Rn, Rm;
5872    ARM_ShifterType shift_t;
5873    uint32_t shift_n; // the shift applied to the value read from Rm
5874    bool setflags;
5875    switch (encoding) {
5876    case eEncodingT1:
5877      Rd = Rn = Bits32(opcode, 2, 0);
5878      Rm = Bits32(opcode, 5, 3);
5879      setflags = !InITBlock();
5880      shift_t = SRType_LSL;
5881      shift_n = 0;
5882      break;
5883    case eEncodingT2:
5884      Rd = Bits32(opcode, 11, 8);
5885      Rn = Bits32(opcode, 19, 16);
5886      Rm = Bits32(opcode, 3, 0);
5887      setflags = BitIsSet(opcode, 20);
5888      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5889      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5890        return false;
5891      break;
5892    case eEncodingA1:
5893      Rd = Bits32(opcode, 15, 12);
5894      Rn = Bits32(opcode, 19, 16);
5895      Rm = Bits32(opcode, 3, 0);
5896      setflags = BitIsSet(opcode, 20);
5897      shift_n = DecodeImmShiftARM(opcode, shift_t);
5898
5899      if (Rd == 15 && setflags)
5900        return EmulateSUBSPcLrEtc(opcode, encoding);
5901      break;
5902    default:
5903      return false;
5904    }
5905
5906    // Read the first operand.
5907    int32_t val1 = ReadCoreReg(Rn, &success);
5908    if (!success)
5909      return false;
5910
5911    // Read the second operand.
5912    int32_t val2 = ReadCoreReg(Rm, &success);
5913    if (!success)
5914      return false;
5915
5916    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5917    if (!success)
5918      return false;
5919    AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5920
5921    EmulateInstruction::Context context;
5922    context.type = EmulateInstruction::eContextImmediate;
5923    context.SetNoArgs();
5924
5925    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5926                                   res.carry_out, res.overflow))
5927      return false;
5928  }
5929  return true;
5930}
5931
5932// This instruction adds an immediate value to the PC value to form a PC-
5933// relative address, and writes the result to the destination register.
5934bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5935                                       const ARMEncoding encoding) {
5936#if 0
5937    // ARM pseudo code...
5938    if ConditionPassed() then
5939        EncodingSpecificOperations();
5940        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5941        if d == 15 then         // Can only occur for ARM encodings
5942            ALUWritePC(result);
5943        else
5944            R[d] = result;
5945#endif
5946
5947  bool success = false;
5948
5949  if (ConditionPassed(opcode)) {
5950    uint32_t Rd;
5951    uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5952    bool add;
5953    switch (encoding) {
5954    case eEncodingT1:
5955      Rd = Bits32(opcode, 10, 8);
5956      imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5957      add = true;
5958      break;
5959    case eEncodingT2:
5960    case eEncodingT3:
5961      Rd = Bits32(opcode, 11, 8);
5962      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5963      add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5964      if (BadReg(Rd))
5965        return false;
5966      break;
5967    case eEncodingA1:
5968    case eEncodingA2:
5969      Rd = Bits32(opcode, 15, 12);
5970      imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
5971      add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5972      break;
5973    default:
5974      return false;
5975    }
5976
5977    // Read the PC value.
5978    uint32_t pc = ReadCoreReg(PC_REG, &success);
5979    if (!success)
5980      return false;
5981
5982    uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5983
5984    EmulateInstruction::Context context;
5985    context.type = EmulateInstruction::eContextImmediate;
5986    context.SetNoArgs();
5987
5988    if (!WriteCoreReg(context, result, Rd))
5989      return false;
5990  }
5991  return true;
5992}
5993
5994// This instruction performs a bitwise AND of a register value and an immediate
5995// value, and writes the result to the destination register.  It can optionally
5996// update the condition flags based on the result.
5997bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
5998                                          const ARMEncoding encoding) {
5999#if 0
6000    // ARM pseudo code...
6001    if ConditionPassed() then
6002        EncodingSpecificOperations();
6003        result = R[n] AND imm32;
6004        if d == 15 then         // Can only occur for ARM encoding
6005            ALUWritePC(result); // setflags is always FALSE here
6006        else
6007            R[d] = result;
6008            if setflags then
6009                APSR.N = result<31>;
6010                APSR.Z = IsZeroBit(result);
6011                APSR.C = carry;
6012                // APSR.V unchanged
6013#endif
6014
6015  bool success = false;
6016
6017  if (ConditionPassed(opcode)) {
6018    uint32_t Rd, Rn;
6019    uint32_t
6020        imm32; // the immediate value to be ANDed to the value obtained from Rn
6021    bool setflags;
6022    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6023    switch (encoding) {
6024    case eEncodingT1:
6025      Rd = Bits32(opcode, 11, 8);
6026      Rn = Bits32(opcode, 19, 16);
6027      setflags = BitIsSet(opcode, 20);
6028      imm32 = ThumbExpandImm_C(
6029          opcode, APSR_C,
6030          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6031      // if Rd == '1111' && S == '1' then SEE TST (immediate);
6032      if (Rd == 15 && setflags)
6033        return EmulateTSTImm(opcode, eEncodingT1);
6034      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6035        return false;
6036      break;
6037    case eEncodingA1:
6038      Rd = Bits32(opcode, 15, 12);
6039      Rn = Bits32(opcode, 19, 16);
6040      setflags = BitIsSet(opcode, 20);
6041      imm32 =
6042          ARMExpandImm_C(opcode, APSR_C,
6043                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6044
6045      if (Rd == 15 && setflags)
6046        return EmulateSUBSPcLrEtc(opcode, encoding);
6047      break;
6048    default:
6049      return false;
6050    }
6051
6052    // Read the first operand.
6053    uint32_t val1 = ReadCoreReg(Rn, &success);
6054    if (!success)
6055      return false;
6056
6057    uint32_t result = val1 & imm32;
6058
6059    EmulateInstruction::Context context;
6060    context.type = EmulateInstruction::eContextImmediate;
6061    context.SetNoArgs();
6062
6063    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6064      return false;
6065  }
6066  return true;
6067}
6068
6069// This instruction performs a bitwise AND of a register value and an
6070// optionally-shifted register value, and writes the result to the destination
6071// register.  It can optionally update the condition flags based on the result.
6072bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6073                                          const ARMEncoding encoding) {
6074#if 0
6075    // ARM pseudo code...
6076    if ConditionPassed() then
6077        EncodingSpecificOperations();
6078        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6079        result = R[n] AND shifted;
6080        if d == 15 then         // Can only occur for ARM encoding
6081            ALUWritePC(result); // setflags is always FALSE here
6082        else
6083            R[d] = result;
6084            if setflags then
6085                APSR.N = result<31>;
6086                APSR.Z = IsZeroBit(result);
6087                APSR.C = carry;
6088                // APSR.V unchanged
6089#endif
6090
6091  bool success = false;
6092
6093  if (ConditionPassed(opcode)) {
6094    uint32_t Rd, Rn, Rm;
6095    ARM_ShifterType shift_t;
6096    uint32_t shift_n; // the shift applied to the value read from Rm
6097    bool setflags;
6098    uint32_t carry;
6099    switch (encoding) {
6100    case eEncodingT1:
6101      Rd = Rn = Bits32(opcode, 2, 0);
6102      Rm = Bits32(opcode, 5, 3);
6103      setflags = !InITBlock();
6104      shift_t = SRType_LSL;
6105      shift_n = 0;
6106      break;
6107    case eEncodingT2:
6108      Rd = Bits32(opcode, 11, 8);
6109      Rn = Bits32(opcode, 19, 16);
6110      Rm = Bits32(opcode, 3, 0);
6111      setflags = BitIsSet(opcode, 20);
6112      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6113      // if Rd == '1111' && S == '1' then SEE TST (register);
6114      if (Rd == 15 && setflags)
6115        return EmulateTSTReg(opcode, eEncodingT2);
6116      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6117        return false;
6118      break;
6119    case eEncodingA1:
6120      Rd = Bits32(opcode, 15, 12);
6121      Rn = Bits32(opcode, 19, 16);
6122      Rm = Bits32(opcode, 3, 0);
6123      setflags = BitIsSet(opcode, 20);
6124      shift_n = DecodeImmShiftARM(opcode, shift_t);
6125
6126      if (Rd == 15 && setflags)
6127        return EmulateSUBSPcLrEtc(opcode, encoding);
6128      break;
6129    default:
6130      return false;
6131    }
6132
6133    // Read the first operand.
6134    uint32_t val1 = ReadCoreReg(Rn, &success);
6135    if (!success)
6136      return false;
6137
6138    // Read the second operand.
6139    uint32_t val2 = ReadCoreReg(Rm, &success);
6140    if (!success)
6141      return false;
6142
6143    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6144    if (!success)
6145      return false;
6146    uint32_t result = val1 & shifted;
6147
6148    EmulateInstruction::Context context;
6149    context.type = EmulateInstruction::eContextImmediate;
6150    context.SetNoArgs();
6151
6152    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6153      return false;
6154  }
6155  return true;
6156}
6157
6158// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6159// the complement of an immediate value, and writes the result to the
6160// destination register.  It can optionally update the condition flags based on
6161// the result.
6162bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6163                                          const ARMEncoding encoding) {
6164#if 0
6165    // ARM pseudo code...
6166    if ConditionPassed() then
6167        EncodingSpecificOperations();
6168        result = R[n] AND NOT(imm32);
6169        if d == 15 then         // Can only occur for ARM encoding
6170            ALUWritePC(result); // setflags is always FALSE here
6171        else
6172            R[d] = result;
6173            if setflags then
6174                APSR.N = result<31>;
6175                APSR.Z = IsZeroBit(result);
6176                APSR.C = carry;
6177                // APSR.V unchanged
6178#endif
6179
6180  bool success = false;
6181
6182  if (ConditionPassed(opcode)) {
6183    uint32_t Rd, Rn;
6184    uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6185                    // the value obtained from Rn
6186    bool setflags;
6187    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6188    switch (encoding) {
6189    case eEncodingT1:
6190      Rd = Bits32(opcode, 11, 8);
6191      Rn = Bits32(opcode, 19, 16);
6192      setflags = BitIsSet(opcode, 20);
6193      imm32 = ThumbExpandImm_C(
6194          opcode, APSR_C,
6195          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6196      if (BadReg(Rd) || BadReg(Rn))
6197        return false;
6198      break;
6199    case eEncodingA1:
6200      Rd = Bits32(opcode, 15, 12);
6201      Rn = Bits32(opcode, 19, 16);
6202      setflags = BitIsSet(opcode, 20);
6203      imm32 =
6204          ARMExpandImm_C(opcode, APSR_C,
6205                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6206
6207      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6208      // instructions;
6209      if (Rd == 15 && setflags)
6210        return EmulateSUBSPcLrEtc(opcode, encoding);
6211      break;
6212    default:
6213      return false;
6214    }
6215
6216    // Read the first operand.
6217    uint32_t val1 = ReadCoreReg(Rn, &success);
6218    if (!success)
6219      return false;
6220
6221    uint32_t result = val1 & ~imm32;
6222
6223    EmulateInstruction::Context context;
6224    context.type = EmulateInstruction::eContextImmediate;
6225    context.SetNoArgs();
6226
6227    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6228      return false;
6229  }
6230  return true;
6231}
6232
6233// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6234// the complement of an optionally-shifted register value, and writes the
6235// result to the destination register. It can optionally update the condition
6236// flags based on the result.
6237bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6238                                          const ARMEncoding encoding) {
6239#if 0
6240    // ARM pseudo code...
6241    if ConditionPassed() then
6242        EncodingSpecificOperations();
6243        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6244        result = R[n] AND NOT(shifted);
6245        if d == 15 then         // Can only occur for ARM encoding
6246            ALUWritePC(result); // setflags is always FALSE here
6247        else
6248            R[d] = result;
6249            if setflags then
6250                APSR.N = result<31>;
6251                APSR.Z = IsZeroBit(result);
6252                APSR.C = carry;
6253                // APSR.V unchanged
6254#endif
6255
6256  bool success = false;
6257
6258  if (ConditionPassed(opcode)) {
6259    uint32_t Rd, Rn, Rm;
6260    ARM_ShifterType shift_t;
6261    uint32_t shift_n; // the shift applied to the value read from Rm
6262    bool setflags;
6263    uint32_t carry;
6264    switch (encoding) {
6265    case eEncodingT1:
6266      Rd = Rn = Bits32(opcode, 2, 0);
6267      Rm = Bits32(opcode, 5, 3);
6268      setflags = !InITBlock();
6269      shift_t = SRType_LSL;
6270      shift_n = 0;
6271      break;
6272    case eEncodingT2:
6273      Rd = Bits32(opcode, 11, 8);
6274      Rn = Bits32(opcode, 19, 16);
6275      Rm = Bits32(opcode, 3, 0);
6276      setflags = BitIsSet(opcode, 20);
6277      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6278      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6279        return false;
6280      break;
6281    case eEncodingA1:
6282      Rd = Bits32(opcode, 15, 12);
6283      Rn = Bits32(opcode, 19, 16);
6284      Rm = Bits32(opcode, 3, 0);
6285      setflags = BitIsSet(opcode, 20);
6286      shift_n = DecodeImmShiftARM(opcode, shift_t);
6287
6288      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6289      // instructions;
6290      if (Rd == 15 && setflags)
6291        return EmulateSUBSPcLrEtc(opcode, encoding);
6292      break;
6293    default:
6294      return false;
6295    }
6296
6297    // Read the first operand.
6298    uint32_t val1 = ReadCoreReg(Rn, &success);
6299    if (!success)
6300      return false;
6301
6302    // Read the second operand.
6303    uint32_t val2 = ReadCoreReg(Rm, &success);
6304    if (!success)
6305      return false;
6306
6307    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6308    if (!success)
6309      return false;
6310    uint32_t result = val1 & ~shifted;
6311
6312    EmulateInstruction::Context context;
6313    context.type = EmulateInstruction::eContextImmediate;
6314    context.SetNoArgs();
6315
6316    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6317      return false;
6318  }
6319  return true;
6320}
6321
6322// LDR (immediate, ARM) calculates an address from a base register value and an
6323// immediate offset, loads a word
6324// from memory, and writes it to a register.  It can use offset, post-indexed,
6325// or pre-indexed addressing.
6326bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6327                                                   const ARMEncoding encoding) {
6328#if 0
6329    if ConditionPassed() then
6330        EncodingSpecificOperations();
6331        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6332        address = if index then offset_addr else R[n];
6333        data = MemU[address,4];
6334        if wback then R[n] = offset_addr;
6335        if t == 15 then
6336            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6337        elsif UnalignedSupport() || address<1:0> = '00' then
6338            R[t] = data;
6339        else // Can only apply before ARMv7
6340            R[t] = ROR(data, 8*UInt(address<1:0>));
6341#endif
6342
6343  bool success = false;
6344
6345  if (ConditionPassed(opcode)) {
6346    const uint32_t addr_byte_size = GetAddressByteSize();
6347
6348    uint32_t t;
6349    uint32_t n;
6350    uint32_t imm32;
6351    bool index;
6352    bool add;
6353    bool wback;
6354
6355    switch (encoding) {
6356    case eEncodingA1:
6357      // if Rn == '1111' then SEE LDR (literal);
6358      // if P == '0' && W == '1' then SEE LDRT;
6359      // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6360      // '000000000100' then SEE POP;
6361      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6362      t = Bits32(opcode, 15, 12);
6363      n = Bits32(opcode, 19, 16);
6364      imm32 = Bits32(opcode, 11, 0);
6365
6366      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6367      // (W == '1');
6368      index = BitIsSet(opcode, 24);
6369      add = BitIsSet(opcode, 23);
6370      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6371
6372      // if wback && n == t then UNPREDICTABLE;
6373      if (wback && (n == t))
6374        return false;
6375
6376      break;
6377
6378    default:
6379      return false;
6380    }
6381
6382    addr_t address;
6383    addr_t offset_addr;
6384    addr_t base_address = ReadCoreReg(n, &success);
6385    if (!success)
6386      return false;
6387
6388    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6389    if (add)
6390      offset_addr = base_address + imm32;
6391    else
6392      offset_addr = base_address - imm32;
6393
6394    // address = if index then offset_addr else R[n];
6395    if (index)
6396      address = offset_addr;
6397    else
6398      address = base_address;
6399
6400    // data = MemU[address,4];
6401
6402    std::optional<RegisterInfo> base_reg =
6403        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6404    EmulateInstruction::Context context;
6405    context.type = eContextRegisterLoad;
6406    context.SetRegisterPlusOffset(*base_reg, address - base_address);
6407
6408    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6409    if (!success)
6410      return false;
6411
6412    // if wback then R[n] = offset_addr;
6413    if (wback) {
6414      context.type = eContextAdjustBaseRegister;
6415      context.SetAddress(offset_addr);
6416      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6417                                 offset_addr))
6418        return false;
6419    }
6420
6421    // if t == 15 then
6422    if (t == 15) {
6423      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6424      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6425        // LoadWritePC (data);
6426        context.type = eContextRegisterLoad;
6427        context.SetRegisterPlusOffset(*base_reg, address - base_address);
6428        LoadWritePC(context, data);
6429      } else
6430        return false;
6431    }
6432    // elsif UnalignedSupport() || address<1:0> = '00' then
6433    else if (UnalignedSupport() ||
6434             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6435      // R[t] = data;
6436      context.type = eContextRegisterLoad;
6437      context.SetRegisterPlusOffset(*base_reg, address - base_address);
6438      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6439                                 data))
6440        return false;
6441    }
6442    // else // Can only apply before ARMv7
6443    else {
6444      // R[t] = ROR(data, 8*UInt(address<1:0>));
6445      data = ROR(data, Bits32(address, 1, 0), &success);
6446      if (!success)
6447        return false;
6448      context.type = eContextRegisterLoad;
6449      context.SetImmediate(data);
6450      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6451                                 data))
6452        return false;
6453    }
6454  }
6455  return true;
6456}
6457
6458// LDR (register) calculates an address from a base register value and an offset
6459// register value, loads a word
6460// from memory, and writes it to a register.  The offset register value can
6461// optionally be shifted.
6462bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6463                                               const ARMEncoding encoding) {
6464#if 0
6465    if ConditionPassed() then
6466        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6467        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6468        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6469        address = if index then offset_addr else R[n];
6470        data = MemU[address,4];
6471        if wback then R[n] = offset_addr;
6472        if t == 15 then
6473            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6474        elsif UnalignedSupport() || address<1:0> = '00' then
6475            R[t] = data;
6476        else // Can only apply before ARMv7
6477            if CurrentInstrSet() == InstrSet_ARM then
6478                R[t] = ROR(data, 8*UInt(address<1:0>));
6479            else
6480                R[t] = bits(32) UNKNOWN;
6481#endif
6482
6483  bool success = false;
6484
6485  if (ConditionPassed(opcode)) {
6486    const uint32_t addr_byte_size = GetAddressByteSize();
6487
6488    uint32_t t;
6489    uint32_t n;
6490    uint32_t m;
6491    bool index;
6492    bool add;
6493    bool wback;
6494    ARM_ShifterType shift_t;
6495    uint32_t shift_n;
6496
6497    switch (encoding) {
6498    case eEncodingT1:
6499      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6500      // in ThumbEE";
6501      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6502      t = Bits32(opcode, 2, 0);
6503      n = Bits32(opcode, 5, 3);
6504      m = Bits32(opcode, 8, 6);
6505
6506      // index = TRUE; add = TRUE; wback = FALSE;
6507      index = true;
6508      add = true;
6509      wback = false;
6510
6511      // (shift_t, shift_n) = (SRType_LSL, 0);
6512      shift_t = SRType_LSL;
6513      shift_n = 0;
6514
6515      break;
6516
6517    case eEncodingT2:
6518      // if Rn == '1111' then SEE LDR (literal);
6519      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6520      t = Bits32(opcode, 15, 12);
6521      n = Bits32(opcode, 19, 16);
6522      m = Bits32(opcode, 3, 0);
6523
6524      // index = TRUE; add = TRUE; wback = FALSE;
6525      index = true;
6526      add = true;
6527      wback = false;
6528
6529      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6530      shift_t = SRType_LSL;
6531      shift_n = Bits32(opcode, 5, 4);
6532
6533      // if BadReg(m) then UNPREDICTABLE;
6534      if (BadReg(m))
6535        return false;
6536
6537      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6538      if ((t == 15) && InITBlock() && !LastInITBlock())
6539        return false;
6540
6541      break;
6542
6543    case eEncodingA1: {
6544      // if P == '0' && W == '1' then SEE LDRT;
6545      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6546      t = Bits32(opcode, 15, 12);
6547      n = Bits32(opcode, 19, 16);
6548      m = Bits32(opcode, 3, 0);
6549
6550      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6551      // (W == '1');
6552      index = BitIsSet(opcode, 24);
6553      add = BitIsSet(opcode, 23);
6554      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6555
6556      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6557      uint32_t type = Bits32(opcode, 6, 5);
6558      uint32_t imm5 = Bits32(opcode, 11, 7);
6559      shift_n = DecodeImmShift(type, imm5, shift_t);
6560
6561      // if m == 15 then UNPREDICTABLE;
6562      if (m == 15)
6563        return false;
6564
6565      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6566      if (wback && ((n == 15) || (n == t)))
6567        return false;
6568    } break;
6569
6570    default:
6571      return false;
6572    }
6573
6574    uint32_t Rm =
6575        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6576    if (!success)
6577      return false;
6578
6579    uint32_t Rn =
6580        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6581    if (!success)
6582      return false;
6583
6584    addr_t offset_addr;
6585    addr_t address;
6586
6587    // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is
6588    // an application level alias for the CPSR".
6589    addr_t offset =
6590        Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6591    if (!success)
6592      return false;
6593
6594    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6595    if (add)
6596      offset_addr = Rn + offset;
6597    else
6598      offset_addr = Rn - offset;
6599
6600    // address = if index then offset_addr else R[n];
6601    if (index)
6602      address = offset_addr;
6603    else
6604      address = Rn;
6605
6606    // data = MemU[address,4];
6607    std::optional<RegisterInfo> base_reg =
6608        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6609    EmulateInstruction::Context context;
6610    context.type = eContextRegisterLoad;
6611    context.SetRegisterPlusOffset(*base_reg, address - Rn);
6612
6613    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6614    if (!success)
6615      return false;
6616
6617    // if wback then R[n] = offset_addr;
6618    if (wback) {
6619      context.type = eContextAdjustBaseRegister;
6620      context.SetAddress(offset_addr);
6621      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6622                                 offset_addr))
6623        return false;
6624    }
6625
6626    // if t == 15 then
6627    if (t == 15) {
6628      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6629      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6630        context.type = eContextRegisterLoad;
6631        context.SetRegisterPlusOffset(*base_reg, address - Rn);
6632        LoadWritePC(context, data);
6633      } else
6634        return false;
6635    }
6636    // elsif UnalignedSupport() || address<1:0> = '00' then
6637    else if (UnalignedSupport() ||
6638             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6639      // R[t] = data;
6640      context.type = eContextRegisterLoad;
6641      context.SetRegisterPlusOffset(*base_reg, address - Rn);
6642      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6643                                 data))
6644        return false;
6645    } else // Can only apply before ARMv7
6646    {
6647      // if CurrentInstrSet() == InstrSet_ARM then
6648      if (CurrentInstrSet() == eModeARM) {
6649        // R[t] = ROR(data, 8*UInt(address<1:0>));
6650        data = ROR(data, Bits32(address, 1, 0), &success);
6651        if (!success)
6652          return false;
6653        context.type = eContextRegisterLoad;
6654        context.SetImmediate(data);
6655        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6656                                   data))
6657          return false;
6658      } else {
6659        // R[t] = bits(32) UNKNOWN;
6660        WriteBits32Unknown(t);
6661      }
6662    }
6663  }
6664  return true;
6665}
6666
6667// LDRB (immediate, Thumb)
6668bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6669                                                 const ARMEncoding encoding) {
6670#if 0
6671    if ConditionPassed() then
6672        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6673        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6674        address = if index then offset_addr else R[n];
6675        R[t] = ZeroExtend(MemU[address,1], 32);
6676        if wback then R[n] = offset_addr;
6677#endif
6678
6679  bool success = false;
6680
6681  if (ConditionPassed(opcode)) {
6682    uint32_t t;
6683    uint32_t n;
6684    uint32_t imm32;
6685    bool index;
6686    bool add;
6687    bool wback;
6688
6689    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6690    switch (encoding) {
6691    case eEncodingT1:
6692      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6693      t = Bits32(opcode, 2, 0);
6694      n = Bits32(opcode, 5, 3);
6695      imm32 = Bits32(opcode, 10, 6);
6696
6697      // index = TRUE; add = TRUE; wback = FALSE;
6698      index = true;
6699      add = true;
6700      wback = false;
6701
6702      break;
6703
6704    case eEncodingT2:
6705      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6706      t = Bits32(opcode, 15, 12);
6707      n = Bits32(opcode, 19, 16);
6708      imm32 = Bits32(opcode, 11, 0);
6709
6710      // index = TRUE; add = TRUE; wback = FALSE;
6711      index = true;
6712      add = true;
6713      wback = false;
6714
6715      // if Rt == '1111' then SEE PLD;
6716      if (t == 15)
6717        return false; // PLD is not implemented yet
6718
6719      // if Rn == '1111' then SEE LDRB (literal);
6720      if (n == 15)
6721        return EmulateLDRBLiteral(opcode, eEncodingT1);
6722
6723      // if t == 13 then UNPREDICTABLE;
6724      if (t == 13)
6725        return false;
6726
6727      break;
6728
6729    case eEncodingT3:
6730      // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6731      // if P == '0' && W == '0' then UNDEFINED;
6732      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6733        return false;
6734
6735      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6736      t = Bits32(opcode, 15, 12);
6737      n = Bits32(opcode, 19, 16);
6738      imm32 = Bits32(opcode, 7, 0);
6739
6740      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6741      index = BitIsSet(opcode, 10);
6742      add = BitIsSet(opcode, 9);
6743      wback = BitIsSet(opcode, 8);
6744
6745      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6746      if (t == 15)
6747        return false; // PLD is not implemented yet
6748
6749      // if Rn == '1111' then SEE LDRB (literal);
6750      if (n == 15)
6751        return EmulateLDRBLiteral(opcode, eEncodingT1);
6752
6753      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6754      if (BadReg(t) || (wback && (n == t)))
6755        return false;
6756
6757      break;
6758
6759    default:
6760      return false;
6761    }
6762
6763    uint32_t Rn =
6764        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6765    if (!success)
6766      return false;
6767
6768    addr_t address;
6769    addr_t offset_addr;
6770
6771    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6772    if (add)
6773      offset_addr = Rn + imm32;
6774    else
6775      offset_addr = Rn - imm32;
6776
6777    // address = if index then offset_addr else R[n];
6778    if (index)
6779      address = offset_addr;
6780    else
6781      address = Rn;
6782
6783    // R[t] = ZeroExtend(MemU[address,1], 32);
6784    std::optional<RegisterInfo> base_reg =
6785        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6786    std::optional<RegisterInfo> data_reg =
6787        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
6788
6789    EmulateInstruction::Context context;
6790    context.type = eContextRegisterLoad;
6791    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
6792
6793    uint64_t data = MemURead(context, address, 1, 0, &success);
6794    if (!success)
6795      return false;
6796
6797    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6798      return false;
6799
6800    // if wback then R[n] = offset_addr;
6801    if (wback) {
6802      context.type = eContextAdjustBaseRegister;
6803      context.SetAddress(offset_addr);
6804      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6805                                 offset_addr))
6806        return false;
6807    }
6808  }
6809  return true;
6810}
6811
6812// LDRB (literal) calculates an address from the PC value and an immediate
6813// offset, loads a byte from memory,
6814// zero-extends it to form a 32-bit word and writes it to a register.
6815bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6816                                               const ARMEncoding encoding) {
6817#if 0
6818    if ConditionPassed() then
6819        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6820        base = Align(PC,4);
6821        address = if add then (base + imm32) else (base - imm32);
6822        R[t] = ZeroExtend(MemU[address,1], 32);
6823#endif
6824
6825  bool success = false;
6826
6827  if (ConditionPassed(opcode)) {
6828    uint32_t t;
6829    uint32_t imm32;
6830    bool add;
6831    switch (encoding) {
6832    case eEncodingT1:
6833      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6834      t = Bits32(opcode, 15, 12);
6835      imm32 = Bits32(opcode, 11, 0);
6836      add = BitIsSet(opcode, 23);
6837
6838      // if Rt == '1111' then SEE PLD;
6839      if (t == 15)
6840        return false; // PLD is not implemented yet
6841
6842      // if t == 13 then UNPREDICTABLE;
6843      if (t == 13)
6844        return false;
6845
6846      break;
6847
6848    case eEncodingA1:
6849      // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6850      t = Bits32(opcode, 15, 12);
6851      imm32 = Bits32(opcode, 11, 0);
6852      add = BitIsSet(opcode, 23);
6853
6854      // if t == 15 then UNPREDICTABLE;
6855      if (t == 15)
6856        return false;
6857      break;
6858
6859    default:
6860      return false;
6861    }
6862
6863    // base = Align(PC,4);
6864    uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6865    if (!success)
6866      return false;
6867
6868    uint32_t base = AlignPC(pc_val);
6869
6870    addr_t address;
6871    // address = if add then (base + imm32) else (base - imm32);
6872    if (add)
6873      address = base + imm32;
6874    else
6875      address = base - imm32;
6876
6877    // R[t] = ZeroExtend(MemU[address,1], 32);
6878    EmulateInstruction::Context context;
6879    context.type = eContextRelativeBranchImmediate;
6880    context.SetImmediate(address - base);
6881
6882    uint64_t data = MemURead(context, address, 1, 0, &success);
6883    if (!success)
6884      return false;
6885
6886    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6887      return false;
6888  }
6889  return true;
6890}
6891
6892// LDRB (register) calculates an address from a base register value and an
6893// offset rigister value, loads a byte from memory, zero-extends it to form a
6894// 32-bit word, and writes it to a register. The offset register value can
6895// optionally be shifted.
6896bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6897                                                const ARMEncoding encoding) {
6898#if 0
6899    if ConditionPassed() then
6900        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6901        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6902        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6903        address = if index then offset_addr else R[n];
6904        R[t] = ZeroExtend(MemU[address,1],32);
6905        if wback then R[n] = offset_addr;
6906#endif
6907
6908  bool success = false;
6909
6910  if (ConditionPassed(opcode)) {
6911    uint32_t t;
6912    uint32_t n;
6913    uint32_t m;
6914    bool index;
6915    bool add;
6916    bool wback;
6917    ARM_ShifterType shift_t;
6918    uint32_t shift_n;
6919
6920    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6921    switch (encoding) {
6922    case eEncodingT1:
6923      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6924      t = Bits32(opcode, 2, 0);
6925      n = Bits32(opcode, 5, 3);
6926      m = Bits32(opcode, 8, 6);
6927
6928      // index = TRUE; add = TRUE; wback = FALSE;
6929      index = true;
6930      add = true;
6931      wback = false;
6932
6933      // (shift_t, shift_n) = (SRType_LSL, 0);
6934      shift_t = SRType_LSL;
6935      shift_n = 0;
6936      break;
6937
6938    case eEncodingT2:
6939      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6940      t = Bits32(opcode, 15, 12);
6941      n = Bits32(opcode, 19, 16);
6942      m = Bits32(opcode, 3, 0);
6943
6944      // index = TRUE; add = TRUE; wback = FALSE;
6945      index = true;
6946      add = true;
6947      wback = false;
6948
6949      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6950      shift_t = SRType_LSL;
6951      shift_n = Bits32(opcode, 5, 4);
6952
6953      // if Rt == '1111' then SEE PLD;
6954      if (t == 15)
6955        return false; // PLD is not implemented yet
6956
6957      // if Rn == '1111' then SEE LDRB (literal);
6958      if (n == 15)
6959        return EmulateLDRBLiteral(opcode, eEncodingT1);
6960
6961      // if t == 13 || BadReg(m) then UNPREDICTABLE;
6962      if ((t == 13) || BadReg(m))
6963        return false;
6964      break;
6965
6966    case eEncodingA1: {
6967      // if P == '0' && W == '1' then SEE LDRBT;
6968      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6969      t = Bits32(opcode, 15, 12);
6970      n = Bits32(opcode, 19, 16);
6971      m = Bits32(opcode, 3, 0);
6972
6973      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6974      // (W == '1');
6975      index = BitIsSet(opcode, 24);
6976      add = BitIsSet(opcode, 23);
6977      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6978
6979      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6980      uint32_t type = Bits32(opcode, 6, 5);
6981      uint32_t imm5 = Bits32(opcode, 11, 7);
6982      shift_n = DecodeImmShift(type, imm5, shift_t);
6983
6984      // if t == 15 || m == 15 then UNPREDICTABLE;
6985      if ((t == 15) || (m == 15))
6986        return false;
6987
6988      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6989      if (wback && ((n == 15) || (n == t)))
6990        return false;
6991    } break;
6992
6993    default:
6994      return false;
6995    }
6996
6997    addr_t offset_addr;
6998    addr_t address;
6999
7000    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7001    uint32_t Rm =
7002        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7003    if (!success)
7004      return false;
7005
7006    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7007    if (!success)
7008      return false;
7009
7010    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7011    uint32_t Rn =
7012        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7013    if (!success)
7014      return false;
7015
7016    if (add)
7017      offset_addr = Rn + offset;
7018    else
7019      offset_addr = Rn - offset;
7020
7021    // address = if index then offset_addr else R[n];
7022    if (index)
7023      address = offset_addr;
7024    else
7025      address = Rn;
7026
7027    // R[t] = ZeroExtend(MemU[address,1],32);
7028    std::optional<RegisterInfo> base_reg =
7029        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7030
7031    EmulateInstruction::Context context;
7032    context.type = eContextRegisterLoad;
7033    context.SetRegisterPlusOffset(*base_reg, address - Rn);
7034
7035    uint64_t data = MemURead(context, address, 1, 0, &success);
7036    if (!success)
7037      return false;
7038
7039    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7040      return false;
7041
7042    // if wback then R[n] = offset_addr;
7043    if (wback) {
7044      context.type = eContextAdjustBaseRegister;
7045      context.SetAddress(offset_addr);
7046      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7047                                 offset_addr))
7048        return false;
7049    }
7050  }
7051  return true;
7052}
7053
7054// LDRH (immediate, Thumb) calculates an address from a base register value and
7055// an immediate offset, loads a
7056// halfword from memory, zero-extends it to form a 32-bit word, and writes it
7057// to a register.  It can use offset, post-indexed, or pre-indexed addressing.
7058bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7059                                                 const ARMEncoding encoding) {
7060#if 0
7061    if ConditionPassed() then
7062        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7063        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7064        address = if index then offset_addr else R[n];
7065        data = MemU[address,2];
7066        if wback then R[n] = offset_addr;
7067        if UnalignedSupport() || address<0> = '0' then
7068            R[t] = ZeroExtend(data, 32);
7069        else // Can only apply before ARMv7
7070            R[t] = bits(32) UNKNOWN;
7071#endif
7072
7073  bool success = false;
7074
7075  if (ConditionPassed(opcode)) {
7076    uint32_t t;
7077    uint32_t n;
7078    uint32_t imm32;
7079    bool index;
7080    bool add;
7081    bool wback;
7082
7083    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7084    switch (encoding) {
7085    case eEncodingT1:
7086      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7087      t = Bits32(opcode, 2, 0);
7088      n = Bits32(opcode, 5, 3);
7089      imm32 = Bits32(opcode, 10, 6) << 1;
7090
7091      // index = TRUE; add = TRUE; wback = FALSE;
7092      index = true;
7093      add = true;
7094      wback = false;
7095
7096      break;
7097
7098    case eEncodingT2:
7099      // if Rt == '1111' then SEE "Unallocated memory hints";
7100      // if Rn == '1111' then SEE LDRH (literal);
7101      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7102      t = Bits32(opcode, 15, 12);
7103      n = Bits32(opcode, 19, 16);
7104      imm32 = Bits32(opcode, 11, 0);
7105
7106      // index = TRUE; add = TRUE; wback = FALSE;
7107      index = true;
7108      add = true;
7109      wback = false;
7110
7111      // if t == 13 then UNPREDICTABLE;
7112      if (t == 13)
7113        return false;
7114      break;
7115
7116    case eEncodingT3:
7117      // if Rn == '1111' then SEE LDRH (literal);
7118      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7119      // "Unallocated memory hints";
7120      // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7121      // if P == '0' && W == '0' then UNDEFINED;
7122      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7123        return false;
7124
7125      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7126      t = Bits32(opcode, 15, 12);
7127      n = Bits32(opcode, 19, 16);
7128      imm32 = Bits32(opcode, 7, 0);
7129
7130      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7131      index = BitIsSet(opcode, 10);
7132      add = BitIsSet(opcode, 9);
7133      wback = BitIsSet(opcode, 8);
7134
7135      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7136      if (BadReg(t) || (wback && (n == t)))
7137        return false;
7138      break;
7139
7140    default:
7141      return false;
7142    }
7143
7144    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7145    uint32_t Rn =
7146        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7147    if (!success)
7148      return false;
7149
7150    addr_t offset_addr;
7151    addr_t address;
7152
7153    if (add)
7154      offset_addr = Rn + imm32;
7155    else
7156      offset_addr = Rn - imm32;
7157
7158    // address = if index then offset_addr else R[n];
7159    if (index)
7160      address = offset_addr;
7161    else
7162      address = Rn;
7163
7164    // data = MemU[address,2];
7165    std::optional<RegisterInfo> base_reg =
7166        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7167
7168    EmulateInstruction::Context context;
7169    context.type = eContextRegisterLoad;
7170    context.SetRegisterPlusOffset(*base_reg, address - Rn);
7171
7172    uint64_t data = MemURead(context, address, 2, 0, &success);
7173    if (!success)
7174      return false;
7175
7176    // if wback then R[n] = offset_addr;
7177    if (wback) {
7178      context.type = eContextAdjustBaseRegister;
7179      context.SetAddress(offset_addr);
7180      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7181                                 offset_addr))
7182        return false;
7183    }
7184
7185    // if UnalignedSupport() || address<0> = '0' then
7186    if (UnalignedSupport() || BitIsClear(address, 0)) {
7187      // R[t] = ZeroExtend(data, 32);
7188      context.type = eContextRegisterLoad;
7189      context.SetRegisterPlusOffset(*base_reg, address - Rn);
7190      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7191                                 data))
7192        return false;
7193    } else // Can only apply before ARMv7
7194    {
7195      // R[t] = bits(32) UNKNOWN;
7196      WriteBits32Unknown(t);
7197    }
7198  }
7199  return true;
7200}
7201
7202// LDRH (literal) calculates an address from the PC value and an immediate
7203// offset, loads a halfword from memory,
7204// zero-extends it to form a 32-bit word, and writes it to a register.
7205bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7206                                               const ARMEncoding encoding) {
7207#if 0
7208    if ConditionPassed() then
7209        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7210        base = Align(PC,4);
7211        address = if add then (base + imm32) else (base - imm32);
7212        data = MemU[address,2];
7213        if UnalignedSupport() || address<0> = '0' then
7214            R[t] = ZeroExtend(data, 32);
7215        else // Can only apply before ARMv7
7216            R[t] = bits(32) UNKNOWN;
7217#endif
7218
7219  bool success = false;
7220
7221  if (ConditionPassed(opcode)) {
7222    uint32_t t;
7223    uint32_t imm32;
7224    bool add;
7225
7226    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7227    switch (encoding) {
7228    case eEncodingT1:
7229      // if Rt == '1111' then SEE "Unallocated memory hints";
7230      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7231      t = Bits32(opcode, 15, 12);
7232      imm32 = Bits32(opcode, 11, 0);
7233      add = BitIsSet(opcode, 23);
7234
7235      // if t == 13 then UNPREDICTABLE;
7236      if (t == 13)
7237        return false;
7238
7239      break;
7240
7241    case eEncodingA1: {
7242      uint32_t imm4H = Bits32(opcode, 11, 8);
7243      uint32_t imm4L = Bits32(opcode, 3, 0);
7244
7245      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7246      t = Bits32(opcode, 15, 12);
7247      imm32 = (imm4H << 4) | imm4L;
7248      add = BitIsSet(opcode, 23);
7249
7250      // if t == 15 then UNPREDICTABLE;
7251      if (t == 15)
7252        return false;
7253      break;
7254    }
7255
7256    default:
7257      return false;
7258    }
7259
7260    // base = Align(PC,4);
7261    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7262    if (!success)
7263      return false;
7264
7265    addr_t base = AlignPC(pc_value);
7266    addr_t address;
7267
7268    // address = if add then (base + imm32) else (base - imm32);
7269    if (add)
7270      address = base + imm32;
7271    else
7272      address = base - imm32;
7273
7274    // data = MemU[address,2];
7275    std::optional<RegisterInfo> base_reg =
7276        GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7277
7278    EmulateInstruction::Context context;
7279    context.type = eContextRegisterLoad;
7280    context.SetRegisterPlusOffset(*base_reg, address - base);
7281
7282    uint64_t data = MemURead(context, address, 2, 0, &success);
7283    if (!success)
7284      return false;
7285
7286    // if UnalignedSupport() || address<0> = '0' then
7287    if (UnalignedSupport() || BitIsClear(address, 0)) {
7288      // R[t] = ZeroExtend(data, 32);
7289      context.type = eContextRegisterLoad;
7290      context.SetRegisterPlusOffset(*base_reg, address - base);
7291      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7292                                 data))
7293        return false;
7294
7295    } else // Can only apply before ARMv7
7296    {
7297      // R[t] = bits(32) UNKNOWN;
7298      WriteBits32Unknown(t);
7299    }
7300  }
7301  return true;
7302}
7303
7304// LDRH (literal) calculates an address from a base register value and an offset
7305// register value, loads a halfword
7306// from memory, zero-extends it to form a 32-bit word, and writes it to a
7307// register.  The offset register value can be shifted left by 0, 1, 2, or 3
7308// bits.
7309bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7310                                                const ARMEncoding encoding) {
7311#if 0
7312    if ConditionPassed() then
7313        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7314        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7315        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7316        address = if index then offset_addr else R[n];
7317        data = MemU[address,2];
7318        if wback then R[n] = offset_addr;
7319        if UnalignedSupport() || address<0> = '0' then
7320            R[t] = ZeroExtend(data, 32);
7321        else // Can only apply before ARMv7
7322            R[t] = bits(32) UNKNOWN;
7323#endif
7324
7325  bool success = false;
7326
7327  if (ConditionPassed(opcode)) {
7328    uint32_t t;
7329    uint32_t n;
7330    uint32_t m;
7331    bool index;
7332    bool add;
7333    bool wback;
7334    ARM_ShifterType shift_t;
7335    uint32_t shift_n;
7336
7337    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7338    switch (encoding) {
7339    case eEncodingT1:
7340      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7341      // in ThumbEE";
7342      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7343      t = Bits32(opcode, 2, 0);
7344      n = Bits32(opcode, 5, 3);
7345      m = Bits32(opcode, 8, 6);
7346
7347      // index = TRUE; add = TRUE; wback = FALSE;
7348      index = true;
7349      add = true;
7350      wback = false;
7351
7352      // (shift_t, shift_n) = (SRType_LSL, 0);
7353      shift_t = SRType_LSL;
7354      shift_n = 0;
7355
7356      break;
7357
7358    case eEncodingT2:
7359      // if Rn == '1111' then SEE LDRH (literal);
7360      // if Rt == '1111' then SEE "Unallocated memory hints";
7361      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7362      t = Bits32(opcode, 15, 12);
7363      n = Bits32(opcode, 19, 16);
7364      m = Bits32(opcode, 3, 0);
7365
7366      // index = TRUE; add = TRUE; wback = FALSE;
7367      index = true;
7368      add = true;
7369      wback = false;
7370
7371      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7372      shift_t = SRType_LSL;
7373      shift_n = Bits32(opcode, 5, 4);
7374
7375      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7376      if ((t == 13) || BadReg(m))
7377        return false;
7378      break;
7379
7380    case eEncodingA1:
7381      // if P == '0' && W == '1' then SEE LDRHT;
7382      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7383      t = Bits32(opcode, 15, 12);
7384      n = Bits32(opcode, 19, 16);
7385      m = Bits32(opcode, 3, 0);
7386
7387      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7388      // (W == '1');
7389      index = BitIsSet(opcode, 24);
7390      add = BitIsSet(opcode, 23);
7391      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7392
7393      // (shift_t, shift_n) = (SRType_LSL, 0);
7394      shift_t = SRType_LSL;
7395      shift_n = 0;
7396
7397      // if t == 15 || m == 15 then UNPREDICTABLE;
7398      if ((t == 15) || (m == 15))
7399        return false;
7400
7401      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7402      if (wback && ((n == 15) || (n == t)))
7403        return false;
7404
7405      break;
7406
7407    default:
7408      return false;
7409    }
7410
7411    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7412
7413    uint64_t Rm =
7414        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7415    if (!success)
7416      return false;
7417
7418    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7419    if (!success)
7420      return false;
7421
7422    addr_t offset_addr;
7423    addr_t address;
7424
7425    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7426    uint64_t Rn =
7427        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7428    if (!success)
7429      return false;
7430
7431    if (add)
7432      offset_addr = Rn + offset;
7433    else
7434      offset_addr = Rn - offset;
7435
7436    // address = if index then offset_addr else R[n];
7437    if (index)
7438      address = offset_addr;
7439    else
7440      address = Rn;
7441
7442    // data = MemU[address,2];
7443    std::optional<RegisterInfo> base_reg =
7444        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7445    std::optional<RegisterInfo> offset_reg =
7446        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
7447
7448    EmulateInstruction::Context context;
7449    context.type = eContextRegisterLoad;
7450    context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7451    uint64_t data = MemURead(context, address, 2, 0, &success);
7452    if (!success)
7453      return false;
7454
7455    // if wback then R[n] = offset_addr;
7456    if (wback) {
7457      context.type = eContextAdjustBaseRegister;
7458      context.SetAddress(offset_addr);
7459      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7460                                 offset_addr))
7461        return false;
7462    }
7463
7464    // if UnalignedSupport() || address<0> = '0' then
7465    if (UnalignedSupport() || BitIsClear(address, 0)) {
7466      // R[t] = ZeroExtend(data, 32);
7467      context.type = eContextRegisterLoad;
7468      context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7469      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7470                                 data))
7471        return false;
7472    } else // Can only apply before ARMv7
7473    {
7474      // R[t] = bits(32) UNKNOWN;
7475      WriteBits32Unknown(t);
7476    }
7477  }
7478  return true;
7479}
7480
7481// LDRSB (immediate) calculates an address from a base register value and an
7482// immediate offset, loads a byte from
7483// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7484// It can use offset, post-indexed, or pre-indexed addressing.
7485bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7486                                                  const ARMEncoding encoding) {
7487#if 0
7488    if ConditionPassed() then
7489        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7490        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7491        address = if index then offset_addr else R[n];
7492        R[t] = SignExtend(MemU[address,1], 32);
7493        if wback then R[n] = offset_addr;
7494#endif
7495
7496  bool success = false;
7497
7498  if (ConditionPassed(opcode)) {
7499    uint32_t t;
7500    uint32_t n;
7501    uint32_t imm32;
7502    bool index;
7503    bool add;
7504    bool wback;
7505
7506    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7507    switch (encoding) {
7508    case eEncodingT1:
7509      // if Rt == '1111' then SEE PLI;
7510      // if Rn == '1111' then SEE LDRSB (literal);
7511      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7512      t = Bits32(opcode, 15, 12);
7513      n = Bits32(opcode, 19, 16);
7514      imm32 = Bits32(opcode, 11, 0);
7515
7516      // index = TRUE; add = TRUE; wback = FALSE;
7517      index = true;
7518      add = true;
7519      wback = false;
7520
7521      // if t == 13 then UNPREDICTABLE;
7522      if (t == 13)
7523        return false;
7524
7525      break;
7526
7527    case eEncodingT2:
7528      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7529      // if Rn == '1111' then SEE LDRSB (literal);
7530      // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7531      // if P == '0' && W == '0' then UNDEFINED;
7532      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7533        return false;
7534
7535      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7536      t = Bits32(opcode, 15, 12);
7537      n = Bits32(opcode, 19, 16);
7538      imm32 = Bits32(opcode, 7, 0);
7539
7540      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7541      index = BitIsSet(opcode, 10);
7542      add = BitIsSet(opcode, 9);
7543      wback = BitIsSet(opcode, 8);
7544
7545      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7546      if (((t == 13) ||
7547           ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7548                          BitIsSet(opcode, 8)))) ||
7549          (wback && (n == t)))
7550        return false;
7551
7552      break;
7553
7554    case eEncodingA1: {
7555      // if Rn == '1111' then SEE LDRSB (literal);
7556      // if P == '0' && W == '1' then SEE LDRSBT;
7557      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7558      t = Bits32(opcode, 15, 12);
7559      n = Bits32(opcode, 19, 16);
7560
7561      uint32_t imm4H = Bits32(opcode, 11, 8);
7562      uint32_t imm4L = Bits32(opcode, 3, 0);
7563      imm32 = (imm4H << 4) | imm4L;
7564
7565      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7566      // (W == '1');
7567      index = BitIsSet(opcode, 24);
7568      add = BitIsSet(opcode, 23);
7569      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7570
7571      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7572      if ((t == 15) || (wback && (n == t)))
7573        return false;
7574
7575      break;
7576    }
7577
7578    default:
7579      return false;
7580    }
7581
7582    uint64_t Rn = ReadCoreReg(n, &success);
7583    if (!success)
7584      return false;
7585
7586    addr_t offset_addr;
7587    addr_t address;
7588
7589    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7590    if (add)
7591      offset_addr = Rn + imm32;
7592    else
7593      offset_addr = Rn - imm32;
7594
7595    // address = if index then offset_addr else R[n];
7596    if (index)
7597      address = offset_addr;
7598    else
7599      address = Rn;
7600
7601    // R[t] = SignExtend(MemU[address,1], 32);
7602    std::optional<RegisterInfo> base_reg =
7603        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7604
7605    EmulateInstruction::Context context;
7606    context.type = eContextRegisterLoad;
7607    context.SetRegisterPlusOffset(*base_reg, address - Rn);
7608
7609    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7610    if (!success)
7611      return false;
7612
7613    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7614    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7615                               (uint64_t)signed_data))
7616      return false;
7617
7618    // if wback then R[n] = offset_addr;
7619    if (wback) {
7620      context.type = eContextAdjustBaseRegister;
7621      context.SetAddress(offset_addr);
7622      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7623                                 offset_addr))
7624        return false;
7625    }
7626  }
7627
7628  return true;
7629}
7630
7631// LDRSB (literal) calculates an address from the PC value and an immediate
7632// offset, loads a byte from memory,
7633// sign-extends it to form a 32-bit word, and writes tit to a register.
7634bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7635                                                const ARMEncoding encoding) {
7636#if 0
7637    if ConditionPassed() then
7638        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7639        base = Align(PC,4);
7640        address = if add then (base + imm32) else (base - imm32);
7641        R[t] = SignExtend(MemU[address,1], 32);
7642#endif
7643
7644  bool success = false;
7645
7646  if (ConditionPassed(opcode)) {
7647    uint32_t t;
7648    uint32_t imm32;
7649    bool add;
7650
7651    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7652    switch (encoding) {
7653    case eEncodingT1:
7654      // if Rt == '1111' then SEE PLI;
7655      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7656      t = Bits32(opcode, 15, 12);
7657      imm32 = Bits32(opcode, 11, 0);
7658      add = BitIsSet(opcode, 23);
7659
7660      // if t == 13 then UNPREDICTABLE;
7661      if (t == 13)
7662        return false;
7663
7664      break;
7665
7666    case eEncodingA1: {
7667      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7668      t = Bits32(opcode, 15, 12);
7669      uint32_t imm4H = Bits32(opcode, 11, 8);
7670      uint32_t imm4L = Bits32(opcode, 3, 0);
7671      imm32 = (imm4H << 4) | imm4L;
7672      add = BitIsSet(opcode, 23);
7673
7674      // if t == 15 then UNPREDICTABLE;
7675      if (t == 15)
7676        return false;
7677
7678      break;
7679    }
7680
7681    default:
7682      return false;
7683    }
7684
7685    // base = Align(PC,4);
7686    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7687    if (!success)
7688      return false;
7689    uint64_t base = AlignPC(pc_value);
7690
7691    // address = if add then (base + imm32) else (base - imm32);
7692    addr_t address;
7693    if (add)
7694      address = base + imm32;
7695    else
7696      address = base - imm32;
7697
7698    // R[t] = SignExtend(MemU[address,1], 32);
7699    std::optional<RegisterInfo> base_reg =
7700        GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7701
7702    EmulateInstruction::Context context;
7703    context.type = eContextRegisterLoad;
7704    context.SetRegisterPlusOffset(*base_reg, address - base);
7705
7706    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7707    if (!success)
7708      return false;
7709
7710    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7711    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7712                               (uint64_t)signed_data))
7713      return false;
7714  }
7715  return true;
7716}
7717
7718// LDRSB (register) calculates an address from a base register value and an
7719// offset register value, loadsa byte from
7720// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7721// The offset register value can be shifted left by 0, 1, 2, or 3 bits.
7722bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7723                                                 const ARMEncoding encoding) {
7724#if 0
7725    if ConditionPassed() then
7726        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7727        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7728        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7729        address = if index then offset_addr else R[n];
7730        R[t] = SignExtend(MemU[address,1], 32);
7731        if wback then R[n] = offset_addr;
7732#endif
7733
7734  bool success = false;
7735
7736  if (ConditionPassed(opcode)) {
7737    uint32_t t;
7738    uint32_t n;
7739    uint32_t m;
7740    bool index;
7741    bool add;
7742    bool wback;
7743    ARM_ShifterType shift_t;
7744    uint32_t shift_n;
7745
7746    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7747    switch (encoding) {
7748    case eEncodingT1:
7749      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7750      t = Bits32(opcode, 2, 0);
7751      n = Bits32(opcode, 5, 3);
7752      m = Bits32(opcode, 8, 6);
7753
7754      // index = TRUE; add = TRUE; wback = FALSE;
7755      index = true;
7756      add = true;
7757      wback = false;
7758
7759      // (shift_t, shift_n) = (SRType_LSL, 0);
7760      shift_t = SRType_LSL;
7761      shift_n = 0;
7762
7763      break;
7764
7765    case eEncodingT2:
7766      // if Rt == '1111' then SEE PLI;
7767      // if Rn == '1111' then SEE LDRSB (literal);
7768      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7769      t = Bits32(opcode, 15, 12);
7770      n = Bits32(opcode, 19, 16);
7771      m = Bits32(opcode, 3, 0);
7772
7773      // index = TRUE; add = TRUE; wback = FALSE;
7774      index = true;
7775      add = true;
7776      wback = false;
7777
7778      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7779      shift_t = SRType_LSL;
7780      shift_n = Bits32(opcode, 5, 4);
7781
7782      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7783      if ((t == 13) || BadReg(m))
7784        return false;
7785      break;
7786
7787    case eEncodingA1:
7788      // if P == '0' && W == '1' then SEE LDRSBT;
7789      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7790      t = Bits32(opcode, 15, 12);
7791      n = Bits32(opcode, 19, 16);
7792      m = Bits32(opcode, 3, 0);
7793
7794      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7795      // (W == '1');
7796      index = BitIsSet(opcode, 24);
7797      add = BitIsSet(opcode, 23);
7798      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7799
7800      // (shift_t, shift_n) = (SRType_LSL, 0);
7801      shift_t = SRType_LSL;
7802      shift_n = 0;
7803
7804      // if t == 15 || m == 15 then UNPREDICTABLE;
7805      if ((t == 15) || (m == 15))
7806        return false;
7807
7808      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7809      if (wback && ((n == 15) || (n == t)))
7810        return false;
7811      break;
7812
7813    default:
7814      return false;
7815    }
7816
7817    uint64_t Rm =
7818        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7819    if (!success)
7820      return false;
7821
7822    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7823    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7824    if (!success)
7825      return false;
7826
7827    addr_t offset_addr;
7828    addr_t address;
7829
7830    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7831    uint64_t Rn =
7832        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7833    if (!success)
7834      return false;
7835
7836    if (add)
7837      offset_addr = Rn + offset;
7838    else
7839      offset_addr = Rn - offset;
7840
7841    // address = if index then offset_addr else R[n];
7842    if (index)
7843      address = offset_addr;
7844    else
7845      address = Rn;
7846
7847    // R[t] = SignExtend(MemU[address,1], 32);
7848    std::optional<RegisterInfo> base_reg =
7849        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7850    std::optional<RegisterInfo> offset_reg =
7851        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
7852
7853    EmulateInstruction::Context context;
7854    context.type = eContextRegisterLoad;
7855    context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7856
7857    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7858    if (!success)
7859      return false;
7860
7861    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7862    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7863                               (uint64_t)signed_data))
7864      return false;
7865
7866    // if wback then R[n] = offset_addr;
7867    if (wback) {
7868      context.type = eContextAdjustBaseRegister;
7869      context.SetAddress(offset_addr);
7870      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7871                                 offset_addr))
7872        return false;
7873    }
7874  }
7875  return true;
7876}
7877
7878// LDRSH (immediate) calculates an address from a base register value and an
7879// immediate offset, loads a halfword from
7880// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7881// It can use offset, post-indexed, or pre-indexed addressing.
7882bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7883                                                  const ARMEncoding encoding) {
7884#if 0
7885    if ConditionPassed() then
7886        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7887        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7888        address = if index then offset_addr else R[n];
7889        data = MemU[address,2];
7890        if wback then R[n] = offset_addr;
7891        if UnalignedSupport() || address<0> = '0' then
7892            R[t] = SignExtend(data, 32);
7893        else // Can only apply before ARMv7
7894            R[t] = bits(32) UNKNOWN;
7895#endif
7896
7897  bool success = false;
7898
7899  if (ConditionPassed(opcode)) {
7900    uint32_t t;
7901    uint32_t n;
7902    uint32_t imm32;
7903    bool index;
7904    bool add;
7905    bool wback;
7906
7907    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7908    switch (encoding) {
7909    case eEncodingT1:
7910      // if Rn == '1111' then SEE LDRSH (literal);
7911      // if Rt == '1111' then SEE "Unallocated memory hints";
7912      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7913      t = Bits32(opcode, 15, 12);
7914      n = Bits32(opcode, 19, 16);
7915      imm32 = Bits32(opcode, 11, 0);
7916
7917      // index = TRUE; add = TRUE; wback = FALSE;
7918      index = true;
7919      add = true;
7920      wback = false;
7921
7922      // if t == 13 then UNPREDICTABLE;
7923      if (t == 13)
7924        return false;
7925
7926      break;
7927
7928    case eEncodingT2:
7929      // if Rn == '1111' then SEE LDRSH (literal);
7930      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7931      // "Unallocated memory hints";
7932      // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7933      // if P == '0' && W == '0' then UNDEFINED;
7934      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7935        return false;
7936
7937      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7938      t = Bits32(opcode, 15, 12);
7939      n = Bits32(opcode, 19, 16);
7940      imm32 = Bits32(opcode, 7, 0);
7941
7942      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7943      index = BitIsSet(opcode, 10);
7944      add = BitIsSet(opcode, 9);
7945      wback = BitIsSet(opcode, 8);
7946
7947      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7948      if (BadReg(t) || (wback && (n == t)))
7949        return false;
7950
7951      break;
7952
7953    case eEncodingA1: {
7954      // if Rn == '1111' then SEE LDRSH (literal);
7955      // if P == '0' && W == '1' then SEE LDRSHT;
7956      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7957      t = Bits32(opcode, 15, 12);
7958      n = Bits32(opcode, 19, 16);
7959      uint32_t imm4H = Bits32(opcode, 11, 8);
7960      uint32_t imm4L = Bits32(opcode, 3, 0);
7961      imm32 = (imm4H << 4) | imm4L;
7962
7963      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7964      // (W == '1');
7965      index = BitIsSet(opcode, 24);
7966      add = BitIsSet(opcode, 23);
7967      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7968
7969      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7970      if ((t == 15) || (wback && (n == t)))
7971        return false;
7972
7973      break;
7974    }
7975
7976    default:
7977      return false;
7978    }
7979
7980    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7981    uint64_t Rn =
7982        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7983    if (!success)
7984      return false;
7985
7986    addr_t offset_addr;
7987    if (add)
7988      offset_addr = Rn + imm32;
7989    else
7990      offset_addr = Rn - imm32;
7991
7992    // address = if index then offset_addr else R[n];
7993    addr_t address;
7994    if (index)
7995      address = offset_addr;
7996    else
7997      address = Rn;
7998
7999    // data = MemU[address,2];
8000    std::optional<RegisterInfo> base_reg =
8001        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8002
8003    EmulateInstruction::Context context;
8004    context.type = eContextRegisterLoad;
8005    context.SetRegisterPlusOffset(*base_reg, address - Rn);
8006
8007    uint64_t data = MemURead(context, address, 2, 0, &success);
8008    if (!success)
8009      return false;
8010
8011    // if wback then R[n] = offset_addr;
8012    if (wback) {
8013      context.type = eContextAdjustBaseRegister;
8014      context.SetAddress(offset_addr);
8015      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8016                                 offset_addr))
8017        return false;
8018    }
8019
8020    // if UnalignedSupport() || address<0> = '0' then
8021    if (UnalignedSupport() || BitIsClear(address, 0)) {
8022      // R[t] = SignExtend(data, 32);
8023      int64_t signed_data = llvm::SignExtend64<16>(data);
8024      context.type = eContextRegisterLoad;
8025      context.SetRegisterPlusOffset(*base_reg, address - Rn);
8026      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8027                                 (uint64_t)signed_data))
8028        return false;
8029    } else // Can only apply before ARMv7
8030    {
8031      // R[t] = bits(32) UNKNOWN;
8032      WriteBits32Unknown(t);
8033    }
8034  }
8035  return true;
8036}
8037
8038// LDRSH (literal) calculates an address from the PC value and an immediate
8039// offset, loads a halfword from memory,
8040// sign-extends it to from a 32-bit word, and writes it to a register.
8041bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8042                                                const ARMEncoding encoding) {
8043#if 0
8044    if ConditionPassed() then
8045        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8046        base = Align(PC,4);
8047        address = if add then (base + imm32) else (base - imm32);
8048        data = MemU[address,2];
8049        if UnalignedSupport() || address<0> = '0' then
8050            R[t] = SignExtend(data, 32);
8051        else // Can only apply before ARMv7
8052            R[t] = bits(32) UNKNOWN;
8053#endif
8054
8055  bool success = false;
8056
8057  if (ConditionPassed(opcode)) {
8058    uint32_t t;
8059    uint32_t imm32;
8060    bool add;
8061
8062    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8063    switch (encoding) {
8064    case eEncodingT1:
8065      // if Rt == '1111' then SEE "Unallocated memory hints";
8066      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8067      t = Bits32(opcode, 15, 12);
8068      imm32 = Bits32(opcode, 11, 0);
8069      add = BitIsSet(opcode, 23);
8070
8071      // if t == 13 then UNPREDICTABLE;
8072      if (t == 13)
8073        return false;
8074
8075      break;
8076
8077    case eEncodingA1: {
8078      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8079      t = Bits32(opcode, 15, 12);
8080      uint32_t imm4H = Bits32(opcode, 11, 8);
8081      uint32_t imm4L = Bits32(opcode, 3, 0);
8082      imm32 = (imm4H << 4) | imm4L;
8083      add = BitIsSet(opcode, 23);
8084
8085      // if t == 15 then UNPREDICTABLE;
8086      if (t == 15)
8087        return false;
8088
8089      break;
8090    }
8091    default:
8092      return false;
8093    }
8094
8095    // base = Align(PC,4);
8096    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8097    if (!success)
8098      return false;
8099
8100    uint64_t base = AlignPC(pc_value);
8101
8102    addr_t address;
8103    // address = if add then (base + imm32) else (base - imm32);
8104    if (add)
8105      address = base + imm32;
8106    else
8107      address = base - imm32;
8108
8109    // data = MemU[address,2];
8110    std::optional<RegisterInfo> base_reg =
8111        GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
8112
8113    EmulateInstruction::Context context;
8114    context.type = eContextRegisterLoad;
8115    context.SetRegisterPlusOffset(*base_reg, imm32);
8116
8117    uint64_t data = MemURead(context, address, 2, 0, &success);
8118    if (!success)
8119      return false;
8120
8121    // if UnalignedSupport() || address<0> = '0' then
8122    if (UnalignedSupport() || BitIsClear(address, 0)) {
8123      // R[t] = SignExtend(data, 32);
8124      int64_t signed_data = llvm::SignExtend64<16>(data);
8125      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8126                                 (uint64_t)signed_data))
8127        return false;
8128    } else // Can only apply before ARMv7
8129    {
8130      // R[t] = bits(32) UNKNOWN;
8131      WriteBits32Unknown(t);
8132    }
8133  }
8134  return true;
8135}
8136
8137// LDRSH (register) calculates an address from a base register value and an
8138// offset register value, loads a halfword
8139// from memory, sign-extends it to form a 32-bit word, and writes it to a
8140// register.  The offset register value can be shifted left by 0, 1, 2, or 3
8141// bits.
8142bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8143                                                 const ARMEncoding encoding) {
8144#if 0
8145    if ConditionPassed() then
8146        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8147        offset = Shift(R[m], shift_t, shift_n, APSR.C);
8148        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8149        address = if index then offset_addr else R[n];
8150        data = MemU[address,2];
8151        if wback then R[n] = offset_addr;
8152        if UnalignedSupport() || address<0> = '0' then
8153            R[t] = SignExtend(data, 32);
8154        else // Can only apply before ARMv7
8155            R[t] = bits(32) UNKNOWN;
8156#endif
8157
8158  bool success = false;
8159
8160  if (ConditionPassed(opcode)) {
8161    uint32_t t;
8162    uint32_t n;
8163    uint32_t m;
8164    bool index;
8165    bool add;
8166    bool wback;
8167    ARM_ShifterType shift_t;
8168    uint32_t shift_n;
8169
8170    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8171    switch (encoding) {
8172    case eEncodingT1:
8173      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8174      // in ThumbEE";
8175      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8176      t = Bits32(opcode, 2, 0);
8177      n = Bits32(opcode, 5, 3);
8178      m = Bits32(opcode, 8, 6);
8179
8180      // index = TRUE; add = TRUE; wback = FALSE;
8181      index = true;
8182      add = true;
8183      wback = false;
8184
8185      // (shift_t, shift_n) = (SRType_LSL, 0);
8186      shift_t = SRType_LSL;
8187      shift_n = 0;
8188
8189      break;
8190
8191    case eEncodingT2:
8192      // if Rn == '1111' then SEE LDRSH (literal);
8193      // if Rt == '1111' then SEE "Unallocated memory hints";
8194      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8195      t = Bits32(opcode, 15, 12);
8196      n = Bits32(opcode, 19, 16);
8197      m = Bits32(opcode, 3, 0);
8198
8199      // index = TRUE; add = TRUE; wback = FALSE;
8200      index = true;
8201      add = true;
8202      wback = false;
8203
8204      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8205      shift_t = SRType_LSL;
8206      shift_n = Bits32(opcode, 5, 4);
8207
8208      // if t == 13 || BadReg(m) then UNPREDICTABLE;
8209      if ((t == 13) || BadReg(m))
8210        return false;
8211
8212      break;
8213
8214    case eEncodingA1:
8215      // if P == '0' && W == '1' then SEE LDRSHT;
8216      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8217      t = Bits32(opcode, 15, 12);
8218      n = Bits32(opcode, 19, 16);
8219      m = Bits32(opcode, 3, 0);
8220
8221      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
8222      // (W == '1');
8223      index = BitIsSet(opcode, 24);
8224      add = BitIsSet(opcode, 23);
8225      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8226
8227      // (shift_t, shift_n) = (SRType_LSL, 0);
8228      shift_t = SRType_LSL;
8229      shift_n = 0;
8230
8231      // if t == 15 || m == 15 then UNPREDICTABLE;
8232      if ((t == 15) || (m == 15))
8233        return false;
8234
8235      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8236      if (wback && ((n == 15) || (n == t)))
8237        return false;
8238
8239      break;
8240
8241    default:
8242      return false;
8243    }
8244
8245    uint64_t Rm =
8246        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8247    if (!success)
8248      return false;
8249
8250    uint64_t Rn =
8251        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8252    if (!success)
8253      return false;
8254
8255    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8256    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8257    if (!success)
8258      return false;
8259
8260    addr_t offset_addr;
8261    addr_t address;
8262
8263    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8264    if (add)
8265      offset_addr = Rn + offset;
8266    else
8267      offset_addr = Rn - offset;
8268
8269    // address = if index then offset_addr else R[n];
8270    if (index)
8271      address = offset_addr;
8272    else
8273      address = Rn;
8274
8275    // data = MemU[address,2];
8276    std::optional<RegisterInfo> base_reg =
8277        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8278    std::optional<RegisterInfo> offset_reg =
8279        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8280
8281    EmulateInstruction::Context context;
8282    context.type = eContextRegisterLoad;
8283    context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
8284
8285    uint64_t data = MemURead(context, address, 2, 0, &success);
8286    if (!success)
8287      return false;
8288
8289    // if wback then R[n] = offset_addr;
8290    if (wback) {
8291      context.type = eContextAdjustBaseRegister;
8292      context.SetAddress(offset_addr);
8293      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8294                                 offset_addr))
8295        return false;
8296    }
8297
8298    // if UnalignedSupport() || address<0> = '0' then
8299    if (UnalignedSupport() || BitIsClear(address, 0)) {
8300      // R[t] = SignExtend(data, 32);
8301      context.type = eContextRegisterLoad;
8302      context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
8303
8304      int64_t signed_data = llvm::SignExtend64<16>(data);
8305      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8306                                 (uint64_t)signed_data))
8307        return false;
8308    } else // Can only apply before ARMv7
8309    {
8310      // R[t] = bits(32) UNKNOWN;
8311      WriteBits32Unknown(t);
8312    }
8313  }
8314  return true;
8315}
8316
8317// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8318// writes the result to the destination
8319// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8320// extracting the 8-bit value.
8321bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8322                                        const ARMEncoding encoding) {
8323#if 0
8324    if ConditionPassed() then
8325        EncodingSpecificOperations();
8326        rotated = ROR(R[m], rotation);
8327        R[d] = SignExtend(rotated<7:0>, 32);
8328#endif
8329
8330  bool success = false;
8331
8332  if (ConditionPassed(opcode)) {
8333    uint32_t d;
8334    uint32_t m;
8335    uint32_t rotation;
8336
8337    // EncodingSpecificOperations();
8338    switch (encoding) {
8339    case eEncodingT1:
8340      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8341      d = Bits32(opcode, 2, 0);
8342      m = Bits32(opcode, 5, 3);
8343      rotation = 0;
8344
8345      break;
8346
8347    case eEncodingT2:
8348      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8349      d = Bits32(opcode, 11, 8);
8350      m = Bits32(opcode, 3, 0);
8351      rotation = Bits32(opcode, 5, 4) << 3;
8352
8353      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8354      if (BadReg(d) || BadReg(m))
8355        return false;
8356
8357      break;
8358
8359    case eEncodingA1:
8360      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8361      d = Bits32(opcode, 15, 12);
8362      m = Bits32(opcode, 3, 0);
8363      rotation = Bits32(opcode, 11, 10) << 3;
8364
8365      // if d == 15 || m == 15 then UNPREDICTABLE;
8366      if ((d == 15) || (m == 15))
8367        return false;
8368
8369      break;
8370
8371    default:
8372      return false;
8373    }
8374
8375    uint64_t Rm =
8376        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8377    if (!success)
8378      return false;
8379
8380    // rotated = ROR(R[m], rotation);
8381    uint64_t rotated = ROR(Rm, rotation, &success);
8382    if (!success)
8383      return false;
8384
8385    // R[d] = SignExtend(rotated<7:0>, 32);
8386    int64_t data = llvm::SignExtend64<8>(rotated);
8387
8388    std::optional<RegisterInfo> source_reg =
8389        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8390
8391    EmulateInstruction::Context context;
8392    context.type = eContextRegisterLoad;
8393    context.SetRegister(*source_reg);
8394
8395    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8396                               (uint64_t)data))
8397      return false;
8398  }
8399  return true;
8400}
8401
8402// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8403// writes the result to the destination
8404// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8405// extracting the 16-bit value.
8406bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8407                                        const ARMEncoding encoding) {
8408#if 0
8409    if ConditionPassed() then
8410        EncodingSpecificOperations();
8411        rotated = ROR(R[m], rotation);
8412        R[d] = SignExtend(rotated<15:0>, 32);
8413#endif
8414
8415  bool success = false;
8416
8417  if (ConditionPassed(opcode)) {
8418    uint32_t d;
8419    uint32_t m;
8420    uint32_t rotation;
8421
8422    // EncodingSpecificOperations();
8423    switch (encoding) {
8424    case eEncodingT1:
8425      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8426      d = Bits32(opcode, 2, 0);
8427      m = Bits32(opcode, 5, 3);
8428      rotation = 0;
8429
8430      break;
8431
8432    case eEncodingT2:
8433      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8434      d = Bits32(opcode, 11, 8);
8435      m = Bits32(opcode, 3, 0);
8436      rotation = Bits32(opcode, 5, 4) << 3;
8437
8438      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8439      if (BadReg(d) || BadReg(m))
8440        return false;
8441
8442      break;
8443
8444    case eEncodingA1:
8445      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8446      d = Bits32(opcode, 15, 12);
8447      m = Bits32(opcode, 3, 0);
8448      rotation = Bits32(opcode, 11, 10) << 3;
8449
8450      // if d == 15 || m == 15 then UNPREDICTABLE;
8451      if ((d == 15) || (m == 15))
8452        return false;
8453
8454      break;
8455
8456    default:
8457      return false;
8458    }
8459
8460    uint64_t Rm =
8461        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8462    if (!success)
8463      return false;
8464
8465    // rotated = ROR(R[m], rotation);
8466    uint64_t rotated = ROR(Rm, rotation, &success);
8467    if (!success)
8468      return false;
8469
8470    // R[d] = SignExtend(rotated<15:0>, 32);
8471    std::optional<RegisterInfo> source_reg =
8472        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8473
8474    EmulateInstruction::Context context;
8475    context.type = eContextRegisterLoad;
8476    context.SetRegister(*source_reg);
8477
8478    int64_t data = llvm::SignExtend64<16>(rotated);
8479    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8480                               (uint64_t)data))
8481      return false;
8482  }
8483
8484  return true;
8485}
8486
8487// UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and
8488// writes the result to the destination
8489// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8490// extracting the 8-bit value.
8491bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8492                                        const ARMEncoding encoding) {
8493#if 0
8494    if ConditionPassed() then
8495        EncodingSpecificOperations();
8496        rotated = ROR(R[m], rotation);
8497        R[d] = ZeroExtend(rotated<7:0>, 32);
8498#endif
8499
8500  bool success = false;
8501
8502  if (ConditionPassed(opcode)) {
8503    uint32_t d;
8504    uint32_t m;
8505    uint32_t rotation;
8506
8507    // EncodingSpecificOperations();
8508    switch (encoding) {
8509    case eEncodingT1:
8510      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8511      d = Bits32(opcode, 2, 0);
8512      m = Bits32(opcode, 5, 3);
8513      rotation = 0;
8514
8515      break;
8516
8517    case eEncodingT2:
8518      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8519      d = Bits32(opcode, 11, 8);
8520      m = Bits32(opcode, 3, 0);
8521      rotation = Bits32(opcode, 5, 4) << 3;
8522
8523      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8524      if (BadReg(d) || BadReg(m))
8525        return false;
8526
8527      break;
8528
8529    case eEncodingA1:
8530      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8531      d = Bits32(opcode, 15, 12);
8532      m = Bits32(opcode, 3, 0);
8533      rotation = Bits32(opcode, 11, 10) << 3;
8534
8535      // if d == 15 || m == 15 then UNPREDICTABLE;
8536      if ((d == 15) || (m == 15))
8537        return false;
8538
8539      break;
8540
8541    default:
8542      return false;
8543    }
8544
8545    uint64_t Rm =
8546        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8547    if (!success)
8548      return false;
8549
8550    // rotated = ROR(R[m], rotation);
8551    uint64_t rotated = ROR(Rm, rotation, &success);
8552    if (!success)
8553      return false;
8554
8555    // R[d] = ZeroExtend(rotated<7:0>, 32);
8556    std::optional<RegisterInfo> source_reg =
8557        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8558
8559    EmulateInstruction::Context context;
8560    context.type = eContextRegisterLoad;
8561    context.SetRegister(*source_reg);
8562
8563    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8564                               Bits32(rotated, 7, 0)))
8565      return false;
8566  }
8567  return true;
8568}
8569
8570// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8571// writes the result to the destination
8572// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8573// extracting the 16-bit value.
8574bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8575                                        const ARMEncoding encoding) {
8576#if 0
8577    if ConditionPassed() then
8578        EncodingSpecificOperations();
8579        rotated = ROR(R[m], rotation);
8580        R[d] = ZeroExtend(rotated<15:0>, 32);
8581#endif
8582
8583  bool success = false;
8584
8585  if (ConditionPassed(opcode)) {
8586    uint32_t d;
8587    uint32_t m;
8588    uint32_t rotation;
8589
8590    switch (encoding) {
8591    case eEncodingT1:
8592      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8593      d = Bits32(opcode, 2, 0);
8594      m = Bits32(opcode, 5, 3);
8595      rotation = 0;
8596
8597      break;
8598
8599    case eEncodingT2:
8600      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8601      d = Bits32(opcode, 11, 8);
8602      m = Bits32(opcode, 3, 0);
8603      rotation = Bits32(opcode, 5, 4) << 3;
8604
8605      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8606      if (BadReg(d) || BadReg(m))
8607        return false;
8608
8609      break;
8610
8611    case eEncodingA1:
8612      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8613      d = Bits32(opcode, 15, 12);
8614      m = Bits32(opcode, 3, 0);
8615      rotation = Bits32(opcode, 11, 10) << 3;
8616
8617      // if d == 15 || m == 15 then UNPREDICTABLE;
8618      if ((d == 15) || (m == 15))
8619        return false;
8620
8621      break;
8622
8623    default:
8624      return false;
8625    }
8626
8627    uint64_t Rm =
8628        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8629    if (!success)
8630      return false;
8631
8632    // rotated = ROR(R[m], rotation);
8633    uint64_t rotated = ROR(Rm, rotation, &success);
8634    if (!success)
8635      return false;
8636
8637    // R[d] = ZeroExtend(rotated<15:0>, 32);
8638    std::optional<RegisterInfo> source_reg =
8639        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8640
8641    EmulateInstruction::Context context;
8642    context.type = eContextRegisterLoad;
8643    context.SetRegister(*source_reg);
8644
8645    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8646                               Bits32(rotated, 15, 0)))
8647      return false;
8648  }
8649  return true;
8650}
8651
8652// RFE (Return From Exception) loads the PC and the CPSR from the word at the
8653// specified address and the following
8654// word respectively.
8655bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8656                                       const ARMEncoding encoding) {
8657#if 0
8658    if ConditionPassed() then
8659        EncodingSpecificOperations();
8660        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8661            UNPREDICTABLE;
8662        else
8663            address = if increment then R[n] else R[n]-8;
8664            if wordhigher then address = address+4;
8665            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8666            BranchWritePC(MemA[address,4]);
8667            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8668#endif
8669
8670  bool success = false;
8671
8672  if (ConditionPassed(opcode)) {
8673    uint32_t n;
8674    bool wback;
8675    bool increment;
8676    bool wordhigher;
8677
8678    // EncodingSpecificOperations();
8679    switch (encoding) {
8680    case eEncodingT1:
8681      // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8682      // FALSE;
8683      n = Bits32(opcode, 19, 16);
8684      wback = BitIsSet(opcode, 21);
8685      increment = false;
8686      wordhigher = false;
8687
8688      // if n == 15 then UNPREDICTABLE;
8689      if (n == 15)
8690        return false;
8691
8692      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8693      if (InITBlock() && !LastInITBlock())
8694        return false;
8695
8696      break;
8697
8698    case eEncodingT2:
8699      // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8700      n = Bits32(opcode, 19, 16);
8701      wback = BitIsSet(opcode, 21);
8702      increment = true;
8703      wordhigher = false;
8704
8705      // if n == 15 then UNPREDICTABLE;
8706      if (n == 15)
8707        return false;
8708
8709      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8710      if (InITBlock() && !LastInITBlock())
8711        return false;
8712
8713      break;
8714
8715    case eEncodingA1:
8716      // n = UInt(Rn);
8717      n = Bits32(opcode, 19, 16);
8718
8719      // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8720      wback = BitIsSet(opcode, 21);
8721      increment = BitIsSet(opcode, 23);
8722      wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8723
8724      // if n == 15 then UNPREDICTABLE;
8725      if (n == 15)
8726        return false;
8727
8728      break;
8729
8730    default:
8731      return false;
8732    }
8733
8734    // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8735    // then
8736    if (!CurrentModeIsPrivileged())
8737      // UNPREDICTABLE;
8738      return false;
8739    else {
8740      uint64_t Rn =
8741          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8742      if (!success)
8743        return false;
8744
8745      addr_t address;
8746      // address = if increment then R[n] else R[n]-8;
8747      if (increment)
8748        address = Rn;
8749      else
8750        address = Rn - 8;
8751
8752      // if wordhigher then address = address+4;
8753      if (wordhigher)
8754        address = address + 4;
8755
8756      // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8757      std::optional<RegisterInfo> base_reg =
8758          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8759
8760      EmulateInstruction::Context context;
8761      context.type = eContextReturnFromException;
8762      context.SetRegisterPlusOffset(*base_reg, address - Rn);
8763
8764      uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8765      if (!success)
8766        return false;
8767
8768      CPSRWriteByInstr(data, 15, true);
8769
8770      // BranchWritePC(MemA[address,4]);
8771      uint64_t data2 = MemARead(context, address, 4, 0, &success);
8772      if (!success)
8773        return false;
8774
8775      BranchWritePC(context, data2);
8776
8777      // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8778      if (wback) {
8779        context.type = eContextAdjustBaseRegister;
8780        if (increment) {
8781          context.SetOffset(8);
8782          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8783                                     Rn + 8))
8784            return false;
8785        } else {
8786          context.SetOffset(-8);
8787          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8788                                     Rn - 8))
8789            return false;
8790        }
8791      } // if wback
8792    }
8793  } // if ConditionPassed()
8794  return true;
8795}
8796
8797// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8798// register value and an immediate value, and writes the result to the
8799// destination register.  It can optionally update the condition flags based on
8800// the result.
8801bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8802                                          const ARMEncoding encoding) {
8803#if 0
8804    // ARM pseudo code...
8805    if ConditionPassed() then
8806        EncodingSpecificOperations();
8807        result = R[n] EOR imm32;
8808        if d == 15 then         // Can only occur for ARM encoding
8809            ALUWritePC(result); // setflags is always FALSE here
8810        else
8811            R[d] = result;
8812            if setflags then
8813                APSR.N = result<31>;
8814                APSR.Z = IsZeroBit(result);
8815                APSR.C = carry;
8816                // APSR.V unchanged
8817#endif
8818
8819  bool success = false;
8820
8821  if (ConditionPassed(opcode)) {
8822    uint32_t Rd, Rn;
8823    uint32_t
8824        imm32; // the immediate value to be ORed to the value obtained from Rn
8825    bool setflags;
8826    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8827    switch (encoding) {
8828    case eEncodingT1:
8829      Rd = Bits32(opcode, 11, 8);
8830      Rn = Bits32(opcode, 19, 16);
8831      setflags = BitIsSet(opcode, 20);
8832      imm32 = ThumbExpandImm_C(
8833          opcode, APSR_C,
8834          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8835      // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8836      if (Rd == 15 && setflags)
8837        return EmulateTEQImm(opcode, eEncodingT1);
8838      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8839        return false;
8840      break;
8841    case eEncodingA1:
8842      Rd = Bits32(opcode, 15, 12);
8843      Rn = Bits32(opcode, 19, 16);
8844      setflags = BitIsSet(opcode, 20);
8845      imm32 =
8846          ARMExpandImm_C(opcode, APSR_C,
8847                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8848
8849      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8850      // instructions;
8851      if (Rd == 15 && setflags)
8852        return EmulateSUBSPcLrEtc(opcode, encoding);
8853      break;
8854    default:
8855      return false;
8856    }
8857
8858    // Read the first operand.
8859    uint32_t val1 = ReadCoreReg(Rn, &success);
8860    if (!success)
8861      return false;
8862
8863    uint32_t result = val1 ^ imm32;
8864
8865    EmulateInstruction::Context context;
8866    context.type = EmulateInstruction::eContextImmediate;
8867    context.SetNoArgs();
8868
8869    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8870      return false;
8871  }
8872  return true;
8873}
8874
8875// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8876// register value and an optionally-shifted register value, and writes the
8877// result to the destination register. It can optionally update the condition
8878// flags based on the result.
8879bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8880                                          const ARMEncoding encoding) {
8881#if 0
8882    // ARM pseudo code...
8883    if ConditionPassed() then
8884        EncodingSpecificOperations();
8885        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8886        result = R[n] EOR shifted;
8887        if d == 15 then         // Can only occur for ARM encoding
8888            ALUWritePC(result); // setflags is always FALSE here
8889        else
8890            R[d] = result;
8891            if setflags then
8892                APSR.N = result<31>;
8893                APSR.Z = IsZeroBit(result);
8894                APSR.C = carry;
8895                // APSR.V unchanged
8896#endif
8897
8898  bool success = false;
8899
8900  if (ConditionPassed(opcode)) {
8901    uint32_t Rd, Rn, Rm;
8902    ARM_ShifterType shift_t;
8903    uint32_t shift_n; // the shift applied to the value read from Rm
8904    bool setflags;
8905    uint32_t carry;
8906    switch (encoding) {
8907    case eEncodingT1:
8908      Rd = Rn = Bits32(opcode, 2, 0);
8909      Rm = Bits32(opcode, 5, 3);
8910      setflags = !InITBlock();
8911      shift_t = SRType_LSL;
8912      shift_n = 0;
8913      break;
8914    case eEncodingT2:
8915      Rd = Bits32(opcode, 11, 8);
8916      Rn = Bits32(opcode, 19, 16);
8917      Rm = Bits32(opcode, 3, 0);
8918      setflags = BitIsSet(opcode, 20);
8919      shift_n = DecodeImmShiftThumb(opcode, shift_t);
8920      // if Rd == '1111' && S == '1' then SEE TEQ (register);
8921      if (Rd == 15 && setflags)
8922        return EmulateTEQReg(opcode, eEncodingT1);
8923      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8924        return false;
8925      break;
8926    case eEncodingA1:
8927      Rd = Bits32(opcode, 15, 12);
8928      Rn = Bits32(opcode, 19, 16);
8929      Rm = Bits32(opcode, 3, 0);
8930      setflags = BitIsSet(opcode, 20);
8931      shift_n = DecodeImmShiftARM(opcode, shift_t);
8932
8933      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8934      // instructions;
8935      if (Rd == 15 && setflags)
8936        return EmulateSUBSPcLrEtc(opcode, encoding);
8937      break;
8938    default:
8939      return false;
8940    }
8941
8942    // Read the first operand.
8943    uint32_t val1 = ReadCoreReg(Rn, &success);
8944    if (!success)
8945      return false;
8946
8947    // Read the second operand.
8948    uint32_t val2 = ReadCoreReg(Rm, &success);
8949    if (!success)
8950      return false;
8951
8952    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8953    if (!success)
8954      return false;
8955    uint32_t result = val1 ^ shifted;
8956
8957    EmulateInstruction::Context context;
8958    context.type = EmulateInstruction::eContextImmediate;
8959    context.SetNoArgs();
8960
8961    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8962      return false;
8963  }
8964  return true;
8965}
8966
8967// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8968// and an immediate value, and writes the result to the destination register.
8969// It can optionally update the condition flags based on the result.
8970bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8971                                          const ARMEncoding encoding) {
8972#if 0
8973    // ARM pseudo code...
8974    if ConditionPassed() then
8975        EncodingSpecificOperations();
8976        result = R[n] OR imm32;
8977        if d == 15 then         // Can only occur for ARM encoding
8978            ALUWritePC(result); // setflags is always FALSE here
8979        else
8980            R[d] = result;
8981            if setflags then
8982                APSR.N = result<31>;
8983                APSR.Z = IsZeroBit(result);
8984                APSR.C = carry;
8985                // APSR.V unchanged
8986#endif
8987
8988  bool success = false;
8989
8990  if (ConditionPassed(opcode)) {
8991    uint32_t Rd, Rn;
8992    uint32_t
8993        imm32; // the immediate value to be ORed to the value obtained from Rn
8994    bool setflags;
8995    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8996    switch (encoding) {
8997    case eEncodingT1:
8998      Rd = Bits32(opcode, 11, 8);
8999      Rn = Bits32(opcode, 19, 16);
9000      setflags = BitIsSet(opcode, 20);
9001      imm32 = ThumbExpandImm_C(
9002          opcode, APSR_C,
9003          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9004      // if Rn == '1111' then SEE MOV (immediate);
9005      if (Rn == 15)
9006        return EmulateMOVRdImm(opcode, eEncodingT2);
9007      if (BadReg(Rd) || Rn == 13)
9008        return false;
9009      break;
9010    case eEncodingA1:
9011      Rd = Bits32(opcode, 15, 12);
9012      Rn = Bits32(opcode, 19, 16);
9013      setflags = BitIsSet(opcode, 20);
9014      imm32 =
9015          ARMExpandImm_C(opcode, APSR_C,
9016                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9017
9018      if (Rd == 15 && setflags)
9019        return EmulateSUBSPcLrEtc(opcode, encoding);
9020      break;
9021    default:
9022      return false;
9023    }
9024
9025    // Read the first operand.
9026    uint32_t val1 = ReadCoreReg(Rn, &success);
9027    if (!success)
9028      return false;
9029
9030    uint32_t result = val1 | imm32;
9031
9032    EmulateInstruction::Context context;
9033    context.type = EmulateInstruction::eContextImmediate;
9034    context.SetNoArgs();
9035
9036    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9037      return false;
9038  }
9039  return true;
9040}
9041
9042// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9043// and an optionally-shifted register value, and writes the result to the
9044// destination register.  It can optionally update the condition flags based on
9045// the result.
9046bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9047                                          const ARMEncoding encoding) {
9048#if 0
9049    // ARM pseudo code...
9050    if ConditionPassed() then
9051        EncodingSpecificOperations();
9052        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9053        result = R[n] OR shifted;
9054        if d == 15 then         // Can only occur for ARM encoding
9055            ALUWritePC(result); // setflags is always FALSE here
9056        else
9057            R[d] = result;
9058            if setflags then
9059                APSR.N = result<31>;
9060                APSR.Z = IsZeroBit(result);
9061                APSR.C = carry;
9062                // APSR.V unchanged
9063#endif
9064
9065  bool success = false;
9066
9067  if (ConditionPassed(opcode)) {
9068    uint32_t Rd, Rn, Rm;
9069    ARM_ShifterType shift_t;
9070    uint32_t shift_n; // the shift applied to the value read from Rm
9071    bool setflags;
9072    uint32_t carry;
9073    switch (encoding) {
9074    case eEncodingT1:
9075      Rd = Rn = Bits32(opcode, 2, 0);
9076      Rm = Bits32(opcode, 5, 3);
9077      setflags = !InITBlock();
9078      shift_t = SRType_LSL;
9079      shift_n = 0;
9080      break;
9081    case eEncodingT2:
9082      Rd = Bits32(opcode, 11, 8);
9083      Rn = Bits32(opcode, 19, 16);
9084      Rm = Bits32(opcode, 3, 0);
9085      setflags = BitIsSet(opcode, 20);
9086      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9087      // if Rn == '1111' then SEE MOV (register);
9088      if (Rn == 15)
9089        return EmulateMOVRdRm(opcode, eEncodingT3);
9090      if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9091        return false;
9092      break;
9093    case eEncodingA1:
9094      Rd = Bits32(opcode, 15, 12);
9095      Rn = Bits32(opcode, 19, 16);
9096      Rm = Bits32(opcode, 3, 0);
9097      setflags = BitIsSet(opcode, 20);
9098      shift_n = DecodeImmShiftARM(opcode, shift_t);
9099
9100      if (Rd == 15 && setflags)
9101        return EmulateSUBSPcLrEtc(opcode, encoding);
9102      break;
9103    default:
9104      return false;
9105    }
9106
9107    // Read the first operand.
9108    uint32_t val1 = ReadCoreReg(Rn, &success);
9109    if (!success)
9110      return false;
9111
9112    // Read the second operand.
9113    uint32_t val2 = ReadCoreReg(Rm, &success);
9114    if (!success)
9115      return false;
9116
9117    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9118    if (!success)
9119      return false;
9120    uint32_t result = val1 | shifted;
9121
9122    EmulateInstruction::Context context;
9123    context.type = EmulateInstruction::eContextImmediate;
9124    context.SetNoArgs();
9125
9126    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9127      return false;
9128  }
9129  return true;
9130}
9131
9132// Reverse Subtract (immediate) subtracts a register value from an immediate
9133// value, and writes the result to the destination register. It can optionally
9134// update the condition flags based on the result.
9135bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9136                                          const ARMEncoding encoding) {
9137#if 0
9138    // ARM pseudo code...
9139    if ConditionPassed() then
9140        EncodingSpecificOperations();
9141        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9142        if d == 15 then         // Can only occur for ARM encoding
9143            ALUWritePC(result); // setflags is always FALSE here
9144        else
9145            R[d] = result;
9146            if setflags then
9147                APSR.N = result<31>;
9148                APSR.Z = IsZeroBit(result);
9149                APSR.C = carry;
9150                APSR.V = overflow;
9151#endif
9152
9153  bool success = false;
9154
9155  uint32_t Rd; // the destination register
9156  uint32_t Rn; // the first operand
9157  bool setflags;
9158  uint32_t
9159      imm32; // the immediate value to be added to the value obtained from Rn
9160  switch (encoding) {
9161  case eEncodingT1:
9162    Rd = Bits32(opcode, 2, 0);
9163    Rn = Bits32(opcode, 5, 3);
9164    setflags = !InITBlock();
9165    imm32 = 0;
9166    break;
9167  case eEncodingT2:
9168    Rd = Bits32(opcode, 11, 8);
9169    Rn = Bits32(opcode, 19, 16);
9170    setflags = BitIsSet(opcode, 20);
9171    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9172    if (BadReg(Rd) || BadReg(Rn))
9173      return false;
9174    break;
9175  case eEncodingA1:
9176    Rd = Bits32(opcode, 15, 12);
9177    Rn = Bits32(opcode, 19, 16);
9178    setflags = BitIsSet(opcode, 20);
9179    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9180
9181    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9182    // instructions;
9183    if (Rd == 15 && setflags)
9184      return EmulateSUBSPcLrEtc(opcode, encoding);
9185    break;
9186  default:
9187    return false;
9188  }
9189  // Read the register value from the operand register Rn.
9190  uint32_t reg_val = ReadCoreReg(Rn, &success);
9191  if (!success)
9192    return false;
9193
9194  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9195
9196  EmulateInstruction::Context context;
9197  context.type = EmulateInstruction::eContextImmediate;
9198  context.SetNoArgs();
9199
9200  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9201                                   res.carry_out, res.overflow);
9202}
9203
9204// Reverse Subtract (register) subtracts a register value from an optionally-
9205// shifted register value, and writes the result to the destination register.
9206// It can optionally update the condition flags based on the result.
9207bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9208                                          const ARMEncoding encoding) {
9209#if 0
9210    // ARM pseudo code...
9211    if ConditionPassed() then
9212        EncodingSpecificOperations();
9213        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9214        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9215        if d == 15 then         // Can only occur for ARM encoding
9216            ALUWritePC(result); // setflags is always FALSE here
9217        else
9218            R[d] = result;
9219            if setflags then
9220                APSR.N = result<31>;
9221                APSR.Z = IsZeroBit(result);
9222                APSR.C = carry;
9223                APSR.V = overflow;
9224#endif
9225
9226  bool success = false;
9227
9228  uint32_t Rd; // the destination register
9229  uint32_t Rn; // the first operand
9230  uint32_t Rm; // the second operand
9231  bool setflags;
9232  ARM_ShifterType shift_t;
9233  uint32_t shift_n; // the shift applied to the value read from Rm
9234  switch (encoding) {
9235  case eEncodingT1:
9236    Rd = Bits32(opcode, 11, 8);
9237    Rn = Bits32(opcode, 19, 16);
9238    Rm = Bits32(opcode, 3, 0);
9239    setflags = BitIsSet(opcode, 20);
9240    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9241    // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9242    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9243      return false;
9244    break;
9245  case eEncodingA1:
9246    Rd = Bits32(opcode, 15, 12);
9247    Rn = Bits32(opcode, 19, 16);
9248    Rm = Bits32(opcode, 3, 0);
9249    setflags = BitIsSet(opcode, 20);
9250    shift_n = DecodeImmShiftARM(opcode, shift_t);
9251
9252    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9253    // instructions;
9254    if (Rd == 15 && setflags)
9255      return EmulateSUBSPcLrEtc(opcode, encoding);
9256    break;
9257  default:
9258    return false;
9259  }
9260  // Read the register value from register Rn.
9261  uint32_t val1 = ReadCoreReg(Rn, &success);
9262  if (!success)
9263    return false;
9264
9265  // Read the register value from register Rm.
9266  uint32_t val2 = ReadCoreReg(Rm, &success);
9267  if (!success)
9268    return false;
9269
9270  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9271  if (!success)
9272    return false;
9273  AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9274
9275  EmulateInstruction::Context context;
9276  context.type = EmulateInstruction::eContextImmediate;
9277  context.SetNoArgs();
9278  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9279                                   res.carry_out, res.overflow);
9280}
9281
9282// Reverse Subtract with Carry (immediate) subtracts a register value and the
9283// value of NOT (Carry flag) from an immediate value, and writes the result to
9284// the destination register. It can optionally update the condition flags based
9285// on the result.
9286bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9287                                          const ARMEncoding encoding) {
9288#if 0
9289    // ARM pseudo code...
9290    if ConditionPassed() then
9291        EncodingSpecificOperations();
9292        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9293        if d == 15 then
9294            ALUWritePC(result); // setflags is always FALSE here
9295        else
9296            R[d] = result;
9297            if setflags then
9298                APSR.N = result<31>;
9299                APSR.Z = IsZeroBit(result);
9300                APSR.C = carry;
9301                APSR.V = overflow;
9302#endif
9303
9304  bool success = false;
9305
9306  uint32_t Rd; // the destination register
9307  uint32_t Rn; // the first operand
9308  bool setflags;
9309  uint32_t
9310      imm32; // the immediate value to be added to the value obtained from Rn
9311  switch (encoding) {
9312  case eEncodingA1:
9313    Rd = Bits32(opcode, 15, 12);
9314    Rn = Bits32(opcode, 19, 16);
9315    setflags = BitIsSet(opcode, 20);
9316    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9317
9318    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9319    // instructions;
9320    if (Rd == 15 && setflags)
9321      return EmulateSUBSPcLrEtc(opcode, encoding);
9322    break;
9323  default:
9324    return false;
9325  }
9326  // Read the register value from the operand register Rn.
9327  uint32_t reg_val = ReadCoreReg(Rn, &success);
9328  if (!success)
9329    return false;
9330
9331  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9332
9333  EmulateInstruction::Context context;
9334  context.type = EmulateInstruction::eContextImmediate;
9335  context.SetNoArgs();
9336
9337  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9338                                   res.carry_out, res.overflow);
9339}
9340
9341// Reverse Subtract with Carry (register) subtracts a register value and the
9342// value of NOT (Carry flag) from an optionally-shifted register value, and
9343// writes the result to the destination register. It can optionally update the
9344// condition flags based on the result.
9345bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9346                                          const ARMEncoding encoding) {
9347#if 0
9348    // ARM pseudo code...
9349    if ConditionPassed() then
9350        EncodingSpecificOperations();
9351        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9352        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9353        if d == 15 then
9354            ALUWritePC(result); // setflags is always FALSE here
9355        else
9356            R[d] = result;
9357            if setflags then
9358                APSR.N = result<31>;
9359                APSR.Z = IsZeroBit(result);
9360                APSR.C = carry;
9361                APSR.V = overflow;
9362#endif
9363
9364  bool success = false;
9365
9366  uint32_t Rd; // the destination register
9367  uint32_t Rn; // the first operand
9368  uint32_t Rm; // the second operand
9369  bool setflags;
9370  ARM_ShifterType shift_t;
9371  uint32_t shift_n; // the shift applied to the value read from Rm
9372  switch (encoding) {
9373  case eEncodingA1:
9374    Rd = Bits32(opcode, 15, 12);
9375    Rn = Bits32(opcode, 19, 16);
9376    Rm = Bits32(opcode, 3, 0);
9377    setflags = BitIsSet(opcode, 20);
9378    shift_n = DecodeImmShiftARM(opcode, shift_t);
9379
9380    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9381    // instructions;
9382    if (Rd == 15 && setflags)
9383      return EmulateSUBSPcLrEtc(opcode, encoding);
9384    break;
9385  default:
9386    return false;
9387  }
9388  // Read the register value from register Rn.
9389  uint32_t val1 = ReadCoreReg(Rn, &success);
9390  if (!success)
9391    return false;
9392
9393  // Read the register value from register Rm.
9394  uint32_t val2 = ReadCoreReg(Rm, &success);
9395  if (!success)
9396    return false;
9397
9398  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9399  if (!success)
9400    return false;
9401  AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9402
9403  EmulateInstruction::Context context;
9404  context.type = EmulateInstruction::eContextImmediate;
9405  context.SetNoArgs();
9406  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9407                                   res.carry_out, res.overflow);
9408}
9409
9410// Subtract with Carry (immediate) subtracts an immediate value and the value
9411// of
9412// NOT (Carry flag) from a register value, and writes the result to the
9413// destination register.
9414// It can optionally update the condition flags based on the result.
9415bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9416                                          const ARMEncoding encoding) {
9417#if 0
9418    // ARM pseudo code...
9419    if ConditionPassed() then
9420        EncodingSpecificOperations();
9421        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9422        if d == 15 then         // Can only occur for ARM encoding
9423            ALUWritePC(result); // setflags is always FALSE here
9424        else
9425            R[d] = result;
9426            if setflags then
9427                APSR.N = result<31>;
9428                APSR.Z = IsZeroBit(result);
9429                APSR.C = carry;
9430                APSR.V = overflow;
9431#endif
9432
9433  bool success = false;
9434
9435  uint32_t Rd; // the destination register
9436  uint32_t Rn; // the first operand
9437  bool setflags;
9438  uint32_t
9439      imm32; // the immediate value to be added to the value obtained from Rn
9440  switch (encoding) {
9441  case eEncodingT1:
9442    Rd = Bits32(opcode, 11, 8);
9443    Rn = Bits32(opcode, 19, 16);
9444    setflags = BitIsSet(opcode, 20);
9445    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9446    if (BadReg(Rd) || BadReg(Rn))
9447      return false;
9448    break;
9449  case eEncodingA1:
9450    Rd = Bits32(opcode, 15, 12);
9451    Rn = Bits32(opcode, 19, 16);
9452    setflags = BitIsSet(opcode, 20);
9453    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9454
9455    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9456    // instructions;
9457    if (Rd == 15 && setflags)
9458      return EmulateSUBSPcLrEtc(opcode, encoding);
9459    break;
9460  default:
9461    return false;
9462  }
9463  // Read the register value from the operand register Rn.
9464  uint32_t reg_val = ReadCoreReg(Rn, &success);
9465  if (!success)
9466    return false;
9467
9468  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9469
9470  EmulateInstruction::Context context;
9471  context.type = EmulateInstruction::eContextImmediate;
9472  context.SetNoArgs();
9473
9474  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9475                                   res.carry_out, res.overflow);
9476}
9477
9478// Subtract with Carry (register) subtracts an optionally-shifted register
9479// value and the value of
9480// NOT (Carry flag) from a register value, and writes the result to the
9481// destination register.
9482// It can optionally update the condition flags based on the result.
9483bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9484                                          const ARMEncoding encoding) {
9485#if 0
9486    // ARM pseudo code...
9487    if ConditionPassed() then
9488        EncodingSpecificOperations();
9489        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9490        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9491        if d == 15 then         // Can only occur for ARM encoding
9492            ALUWritePC(result); // setflags is always FALSE here
9493        else
9494            R[d] = result;
9495            if setflags then
9496                APSR.N = result<31>;
9497                APSR.Z = IsZeroBit(result);
9498                APSR.C = carry;
9499                APSR.V = overflow;
9500#endif
9501
9502  bool success = false;
9503
9504  uint32_t Rd; // the destination register
9505  uint32_t Rn; // the first operand
9506  uint32_t Rm; // the second operand
9507  bool setflags;
9508  ARM_ShifterType shift_t;
9509  uint32_t shift_n; // the shift applied to the value read from Rm
9510  switch (encoding) {
9511  case eEncodingT1:
9512    Rd = Rn = Bits32(opcode, 2, 0);
9513    Rm = Bits32(opcode, 5, 3);
9514    setflags = !InITBlock();
9515    shift_t = SRType_LSL;
9516    shift_n = 0;
9517    break;
9518  case eEncodingT2:
9519    Rd = Bits32(opcode, 11, 8);
9520    Rn = Bits32(opcode, 19, 16);
9521    Rm = Bits32(opcode, 3, 0);
9522    setflags = BitIsSet(opcode, 20);
9523    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9524    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9525      return false;
9526    break;
9527  case eEncodingA1:
9528    Rd = Bits32(opcode, 15, 12);
9529    Rn = Bits32(opcode, 19, 16);
9530    Rm = Bits32(opcode, 3, 0);
9531    setflags = BitIsSet(opcode, 20);
9532    shift_n = DecodeImmShiftARM(opcode, shift_t);
9533
9534    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9535    // instructions;
9536    if (Rd == 15 && setflags)
9537      return EmulateSUBSPcLrEtc(opcode, encoding);
9538    break;
9539  default:
9540    return false;
9541  }
9542  // Read the register value from register Rn.
9543  uint32_t val1 = ReadCoreReg(Rn, &success);
9544  if (!success)
9545    return false;
9546
9547  // Read the register value from register Rm.
9548  uint32_t val2 = ReadCoreReg(Rm, &success);
9549  if (!success)
9550    return false;
9551
9552  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9553  if (!success)
9554    return false;
9555  AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9556
9557  EmulateInstruction::Context context;
9558  context.type = EmulateInstruction::eContextImmediate;
9559  context.SetNoArgs();
9560  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9561                                   res.carry_out, res.overflow);
9562}
9563
9564// This instruction subtracts an immediate value from a register value, and
9565// writes the result to the destination register.  It can optionally update the
9566// condition flags based on the result.
9567bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9568                                               const ARMEncoding encoding) {
9569#if 0
9570    // ARM pseudo code...
9571    if ConditionPassed() then
9572        EncodingSpecificOperations();
9573        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9574        R[d] = result;
9575        if setflags then
9576            APSR.N = result<31>;
9577            APSR.Z = IsZeroBit(result);
9578            APSR.C = carry;
9579            APSR.V = overflow;
9580#endif
9581
9582  bool success = false;
9583
9584  uint32_t Rd; // the destination register
9585  uint32_t Rn; // the first operand
9586  bool setflags;
9587  uint32_t imm32; // the immediate value to be subtracted from the value
9588                  // obtained from Rn
9589  switch (encoding) {
9590  case eEncodingT1:
9591    Rd = Bits32(opcode, 2, 0);
9592    Rn = Bits32(opcode, 5, 3);
9593    setflags = !InITBlock();
9594    imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9595    break;
9596  case eEncodingT2:
9597    Rd = Rn = Bits32(opcode, 10, 8);
9598    setflags = !InITBlock();
9599    imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9600    break;
9601  case eEncodingT3:
9602    Rd = Bits32(opcode, 11, 8);
9603    Rn = Bits32(opcode, 19, 16);
9604    setflags = BitIsSet(opcode, 20);
9605    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9606
9607    // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9608    if (Rd == 15 && setflags)
9609      return EmulateCMPImm(opcode, eEncodingT2);
9610
9611    // if Rn == '1101' then SEE SUB (SP minus immediate);
9612    if (Rn == 13)
9613      return EmulateSUBSPImm(opcode, eEncodingT2);
9614
9615    // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9616    if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9617      return false;
9618    break;
9619  case eEncodingT4:
9620    Rd = Bits32(opcode, 11, 8);
9621    Rn = Bits32(opcode, 19, 16);
9622    setflags = BitIsSet(opcode, 20);
9623    imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9624
9625    // if Rn == '1111' then SEE ADR;
9626    if (Rn == 15)
9627      return EmulateADR(opcode, eEncodingT2);
9628
9629    // if Rn == '1101' then SEE SUB (SP minus immediate);
9630    if (Rn == 13)
9631      return EmulateSUBSPImm(opcode, eEncodingT3);
9632
9633    if (BadReg(Rd))
9634      return false;
9635    break;
9636  default:
9637    return false;
9638  }
9639  // Read the register value from the operand register Rn.
9640  uint32_t reg_val = ReadCoreReg(Rn, &success);
9641  if (!success)
9642    return false;
9643
9644  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9645
9646  EmulateInstruction::Context context;
9647  context.type = EmulateInstruction::eContextImmediate;
9648  context.SetNoArgs();
9649
9650  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9651                                   res.carry_out, res.overflow);
9652}
9653
9654// This instruction subtracts an immediate value from a register value, and
9655// writes the result to the destination register.  It can optionally update the
9656// condition flags based on the result.
9657bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9658                                             const ARMEncoding encoding) {
9659#if 0
9660    // ARM pseudo code...
9661    if ConditionPassed() then
9662        EncodingSpecificOperations();
9663        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9664        if d == 15 then
9665            ALUWritePC(result); // setflags is always FALSE here
9666        else
9667            R[d] = result;
9668            if setflags then
9669                APSR.N = result<31>;
9670                APSR.Z = IsZeroBit(result);
9671                APSR.C = carry;
9672                APSR.V = overflow;
9673#endif
9674
9675  bool success = false;
9676
9677  if (ConditionPassed(opcode)) {
9678    uint32_t Rd; // the destination register
9679    uint32_t Rn; // the first operand
9680    bool setflags;
9681    uint32_t imm32; // the immediate value to be subtracted from the value
9682                    // obtained from Rn
9683    switch (encoding) {
9684    case eEncodingA1:
9685      Rd = Bits32(opcode, 15, 12);
9686      Rn = Bits32(opcode, 19, 16);
9687      setflags = BitIsSet(opcode, 20);
9688      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9689
9690      // if Rn == '1111' && S == '0' then SEE ADR;
9691      if (Rn == 15 && !setflags)
9692        return EmulateADR(opcode, eEncodingA2);
9693
9694      // if Rn == '1101' then SEE SUB (SP minus immediate);
9695      if (Rn == 13)
9696        return EmulateSUBSPImm(opcode, eEncodingA1);
9697
9698      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9699      // instructions;
9700      if (Rd == 15 && setflags)
9701        return EmulateSUBSPcLrEtc(opcode, encoding);
9702      break;
9703    default:
9704      return false;
9705    }
9706    // Read the register value from the operand register Rn.
9707    uint32_t reg_val = ReadCoreReg(Rn, &success);
9708    if (!success)
9709      return false;
9710
9711    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9712
9713    EmulateInstruction::Context context;
9714    if (Rd == 13)
9715      context.type = EmulateInstruction::eContextAdjustStackPointer;
9716    else
9717      context.type = EmulateInstruction::eContextRegisterPlusOffset;
9718
9719    std::optional<RegisterInfo> dwarf_reg =
9720        GetRegisterInfo(eRegisterKindDWARF, Rn);
9721    int64_t imm32_signed = imm32;
9722    context.SetRegisterPlusOffset(*dwarf_reg, -imm32_signed);
9723
9724    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9725                                   res.carry_out, res.overflow))
9726      return false;
9727  }
9728  return true;
9729}
9730
9731// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9732// register value and an immediate value.  It updates the condition flags based
9733// on the result, and discards the result.
9734bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9735                                          const ARMEncoding encoding) {
9736#if 0
9737    // ARM pseudo code...
9738    if ConditionPassed() then
9739        EncodingSpecificOperations();
9740        result = R[n] EOR imm32;
9741        APSR.N = result<31>;
9742        APSR.Z = IsZeroBit(result);
9743        APSR.C = carry;
9744        // APSR.V unchanged
9745#endif
9746
9747  bool success = false;
9748
9749  if (ConditionPassed(opcode)) {
9750    uint32_t Rn;
9751    uint32_t
9752        imm32; // the immediate value to be ANDed to the value obtained from Rn
9753    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9754    switch (encoding) {
9755    case eEncodingT1:
9756      Rn = Bits32(opcode, 19, 16);
9757      imm32 = ThumbExpandImm_C(
9758          opcode, APSR_C,
9759          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9760      if (BadReg(Rn))
9761        return false;
9762      break;
9763    case eEncodingA1:
9764      Rn = Bits32(opcode, 19, 16);
9765      imm32 =
9766          ARMExpandImm_C(opcode, APSR_C,
9767                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9768      break;
9769    default:
9770      return false;
9771    }
9772
9773    // Read the first operand.
9774    uint32_t val1 = ReadCoreReg(Rn, &success);
9775    if (!success)
9776      return false;
9777
9778    uint32_t result = val1 ^ imm32;
9779
9780    EmulateInstruction::Context context;
9781    context.type = EmulateInstruction::eContextImmediate;
9782    context.SetNoArgs();
9783
9784    if (!WriteFlags(context, result, carry))
9785      return false;
9786  }
9787  return true;
9788}
9789
9790// Test Equivalence (register) performs a bitwise exclusive OR operation on a
9791// register value and an optionally-shifted register value.  It updates the
9792// condition flags based on the result, and discards the result.
9793bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9794                                          const ARMEncoding encoding) {
9795#if 0
9796    // ARM pseudo code...
9797    if ConditionPassed() then
9798        EncodingSpecificOperations();
9799        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9800        result = R[n] EOR shifted;
9801        APSR.N = result<31>;
9802        APSR.Z = IsZeroBit(result);
9803        APSR.C = carry;
9804        // APSR.V unchanged
9805#endif
9806
9807  bool success = false;
9808
9809  if (ConditionPassed(opcode)) {
9810    uint32_t Rn, Rm;
9811    ARM_ShifterType shift_t;
9812    uint32_t shift_n; // the shift applied to the value read from Rm
9813    uint32_t carry;
9814    switch (encoding) {
9815    case eEncodingT1:
9816      Rn = Bits32(opcode, 19, 16);
9817      Rm = Bits32(opcode, 3, 0);
9818      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9819      if (BadReg(Rn) || BadReg(Rm))
9820        return false;
9821      break;
9822    case eEncodingA1:
9823      Rn = Bits32(opcode, 19, 16);
9824      Rm = Bits32(opcode, 3, 0);
9825      shift_n = DecodeImmShiftARM(opcode, shift_t);
9826      break;
9827    default:
9828      return false;
9829    }
9830
9831    // Read the first operand.
9832    uint32_t val1 = ReadCoreReg(Rn, &success);
9833    if (!success)
9834      return false;
9835
9836    // Read the second operand.
9837    uint32_t val2 = ReadCoreReg(Rm, &success);
9838    if (!success)
9839      return false;
9840
9841    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9842    if (!success)
9843      return false;
9844    uint32_t result = val1 ^ shifted;
9845
9846    EmulateInstruction::Context context;
9847    context.type = EmulateInstruction::eContextImmediate;
9848    context.SetNoArgs();
9849
9850    if (!WriteFlags(context, result, carry))
9851      return false;
9852  }
9853  return true;
9854}
9855
9856// Test (immediate) performs a bitwise AND operation on a register value and an
9857// immediate value. It updates the condition flags based on the result, and
9858// discards the result.
9859bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9860                                          const ARMEncoding encoding) {
9861#if 0
9862    // ARM pseudo code...
9863    if ConditionPassed() then
9864        EncodingSpecificOperations();
9865        result = R[n] AND imm32;
9866        APSR.N = result<31>;
9867        APSR.Z = IsZeroBit(result);
9868        APSR.C = carry;
9869        // APSR.V unchanged
9870#endif
9871
9872  bool success = false;
9873
9874  if (ConditionPassed(opcode)) {
9875    uint32_t Rn;
9876    uint32_t
9877        imm32; // the immediate value to be ANDed to the value obtained from Rn
9878    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9879    switch (encoding) {
9880    case eEncodingT1:
9881      Rn = Bits32(opcode, 19, 16);
9882      imm32 = ThumbExpandImm_C(
9883          opcode, APSR_C,
9884          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9885      if (BadReg(Rn))
9886        return false;
9887      break;
9888    case eEncodingA1:
9889      Rn = Bits32(opcode, 19, 16);
9890      imm32 =
9891          ARMExpandImm_C(opcode, APSR_C,
9892                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9893      break;
9894    default:
9895      return false;
9896    }
9897
9898    // Read the first operand.
9899    uint32_t val1 = ReadCoreReg(Rn, &success);
9900    if (!success)
9901      return false;
9902
9903    uint32_t result = val1 & imm32;
9904
9905    EmulateInstruction::Context context;
9906    context.type = EmulateInstruction::eContextImmediate;
9907    context.SetNoArgs();
9908
9909    if (!WriteFlags(context, result, carry))
9910      return false;
9911  }
9912  return true;
9913}
9914
9915// Test (register) performs a bitwise AND operation on a register value and an
9916// optionally-shifted register value. It updates the condition flags based on
9917// the result, and discards the result.
9918bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9919                                          const ARMEncoding encoding) {
9920#if 0
9921    // ARM pseudo code...
9922    if ConditionPassed() then
9923        EncodingSpecificOperations();
9924        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9925        result = R[n] AND shifted;
9926        APSR.N = result<31>;
9927        APSR.Z = IsZeroBit(result);
9928        APSR.C = carry;
9929        // APSR.V unchanged
9930#endif
9931
9932  bool success = false;
9933
9934  if (ConditionPassed(opcode)) {
9935    uint32_t Rn, Rm;
9936    ARM_ShifterType shift_t;
9937    uint32_t shift_n; // the shift applied to the value read from Rm
9938    uint32_t carry;
9939    switch (encoding) {
9940    case eEncodingT1:
9941      Rn = Bits32(opcode, 2, 0);
9942      Rm = Bits32(opcode, 5, 3);
9943      shift_t = SRType_LSL;
9944      shift_n = 0;
9945      break;
9946    case eEncodingT2:
9947      Rn = Bits32(opcode, 19, 16);
9948      Rm = Bits32(opcode, 3, 0);
9949      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9950      if (BadReg(Rn) || BadReg(Rm))
9951        return false;
9952      break;
9953    case eEncodingA1:
9954      Rn = Bits32(opcode, 19, 16);
9955      Rm = Bits32(opcode, 3, 0);
9956      shift_n = DecodeImmShiftARM(opcode, shift_t);
9957      break;
9958    default:
9959      return false;
9960    }
9961
9962    // Read the first operand.
9963    uint32_t val1 = ReadCoreReg(Rn, &success);
9964    if (!success)
9965      return false;
9966
9967    // Read the second operand.
9968    uint32_t val2 = ReadCoreReg(Rm, &success);
9969    if (!success)
9970      return false;
9971
9972    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9973    if (!success)
9974      return false;
9975    uint32_t result = val1 & shifted;
9976
9977    EmulateInstruction::Context context;
9978    context.type = EmulateInstruction::eContextImmediate;
9979    context.SetNoArgs();
9980
9981    if (!WriteFlags(context, result, carry))
9982      return false;
9983  }
9984  return true;
9985}
9986
9987// A8.6.216 SUB (SP minus register)
9988bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
9989                                            const ARMEncoding encoding) {
9990#if 0
9991    if ConditionPassed() then
9992        EncodingSpecificOperations();
9993        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9994        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9995        if d == 15 then // Can only occur for ARM encoding
9996            ALUWritePC(result); // setflags is always FALSE here
9997        else
9998            R[d] = result;
9999            if setflags then
10000                APSR.N = result<31>;
10001                APSR.Z = IsZeroBit(result);
10002                APSR.C = carry;
10003                APSR.V = overflow;
10004#endif
10005
10006  bool success = false;
10007
10008  if (ConditionPassed(opcode)) {
10009    uint32_t d;
10010    uint32_t m;
10011    bool setflags;
10012    ARM_ShifterType shift_t;
10013    uint32_t shift_n;
10014
10015    switch (encoding) {
10016    case eEncodingT1:
10017      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10018      d = Bits32(opcode, 11, 8);
10019      m = Bits32(opcode, 3, 0);
10020      setflags = BitIsSet(opcode, 20);
10021
10022      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10023      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10024
10025      // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10026      // UNPREDICTABLE;
10027      if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10028        return false;
10029
10030      // if d == 15 || BadReg(m) then UNPREDICTABLE;
10031      if ((d == 15) || BadReg(m))
10032        return false;
10033      break;
10034
10035    case eEncodingA1:
10036      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10037      d = Bits32(opcode, 15, 12);
10038      m = Bits32(opcode, 3, 0);
10039      setflags = BitIsSet(opcode, 20);
10040
10041      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10042      // instructions;
10043      if (d == 15 && setflags)
10044        EmulateSUBSPcLrEtc(opcode, encoding);
10045
10046      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10047      shift_n = DecodeImmShiftARM(opcode, shift_t);
10048      break;
10049
10050    default:
10051      return false;
10052    }
10053
10054    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10055    uint32_t Rm = ReadCoreReg(m, &success);
10056    if (!success)
10057      return false;
10058
10059    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10060    if (!success)
10061      return false;
10062
10063    // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10064    uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10065    if (!success)
10066      return false;
10067
10068    AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10069
10070    EmulateInstruction::Context context;
10071    context.type = eContextArithmetic;
10072    std::optional<RegisterInfo> sp_reg =
10073        GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
10074    std::optional<RegisterInfo> dwarf_reg =
10075        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10076    context.SetRegisterRegisterOperands(*sp_reg, *dwarf_reg);
10077
10078    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10079                                   res.carry_out, res.overflow))
10080      return false;
10081  }
10082  return true;
10083}
10084
10085// A8.6.7 ADD (register-shifted register)
10086bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10087                                               const ARMEncoding encoding) {
10088#if 0
10089    if ConditionPassed() then
10090        EncodingSpecificOperations();
10091        shift_n = UInt(R[s]<7:0>);
10092        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10093        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10094        R[d] = result;
10095        if setflags then
10096            APSR.N = result<31>;
10097            APSR.Z = IsZeroBit(result);
10098            APSR.C = carry;
10099            APSR.V = overflow;
10100#endif
10101
10102  bool success = false;
10103
10104  if (ConditionPassed(opcode)) {
10105    uint32_t d;
10106    uint32_t n;
10107    uint32_t m;
10108    uint32_t s;
10109    bool setflags;
10110    ARM_ShifterType shift_t;
10111
10112    switch (encoding) {
10113    case eEncodingA1:
10114      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10115      d = Bits32(opcode, 15, 12);
10116      n = Bits32(opcode, 19, 16);
10117      m = Bits32(opcode, 3, 0);
10118      s = Bits32(opcode, 11, 8);
10119
10120      // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10121      setflags = BitIsSet(opcode, 20);
10122      shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10123
10124      // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10125      if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10126        return false;
10127      break;
10128
10129    default:
10130      return false;
10131    }
10132
10133    // shift_n = UInt(R[s]<7:0>);
10134    uint32_t Rs = ReadCoreReg(s, &success);
10135    if (!success)
10136      return false;
10137
10138    uint32_t shift_n = Bits32(Rs, 7, 0);
10139
10140    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10141    uint32_t Rm = ReadCoreReg(m, &success);
10142    if (!success)
10143      return false;
10144
10145    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10146    if (!success)
10147      return false;
10148
10149    // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10150    uint32_t Rn = ReadCoreReg(n, &success);
10151    if (!success)
10152      return false;
10153
10154    AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10155
10156    // R[d] = result;
10157    EmulateInstruction::Context context;
10158    context.type = eContextArithmetic;
10159    std::optional<RegisterInfo> reg_n =
10160        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10161    std::optional<RegisterInfo> reg_m =
10162        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10163
10164    context.SetRegisterRegisterOperands(*reg_n, *reg_m);
10165
10166    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10167                               res.result))
10168      return false;
10169
10170    // if setflags then
10171    // APSR.N = result<31>;
10172    // APSR.Z = IsZeroBit(result);
10173    // APSR.C = carry;
10174    // APSR.V = overflow;
10175    if (setflags)
10176      return WriteFlags(context, res.result, res.carry_out, res.overflow);
10177  }
10178  return true;
10179}
10180
10181// A8.6.213 SUB (register)
10182bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10183                                          const ARMEncoding encoding) {
10184#if 0
10185    if ConditionPassed() then
10186        EncodingSpecificOperations();
10187        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10188        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10189        if d == 15 then // Can only occur for ARM encoding
10190            ALUWritePC(result); // setflags is always FALSE here
10191        else
10192            R[d] = result;
10193            if setflags then
10194                APSR.N = result<31>;
10195                APSR.Z = IsZeroBit(result);
10196                APSR.C = carry;
10197                APSR.V = overflow;
10198#endif
10199
10200  bool success = false;
10201
10202  if (ConditionPassed(opcode)) {
10203    uint32_t d;
10204    uint32_t n;
10205    uint32_t m;
10206    bool setflags;
10207    ARM_ShifterType shift_t;
10208    uint32_t shift_n;
10209
10210    switch (encoding) {
10211    case eEncodingT1:
10212      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10213      d = Bits32(opcode, 2, 0);
10214      n = Bits32(opcode, 5, 3);
10215      m = Bits32(opcode, 8, 6);
10216      setflags = !InITBlock();
10217
10218      // (shift_t, shift_n) = (SRType_LSL, 0);
10219      shift_t = SRType_LSL;
10220      shift_n = 0;
10221
10222      break;
10223
10224    case eEncodingT2:
10225      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10226      d = Bits32(opcode, 11, 8);
10227      n = Bits32(opcode, 19, 16);
10228      m = Bits32(opcode, 3, 0);
10229      setflags = BitIsSet(opcode, 20);
10230
10231      // if Rd == "1111" && S == "1" then SEE CMP (register);
10232      if (d == 15 && setflags == 1)
10233        return EmulateCMPImm(opcode, eEncodingT3);
10234
10235      // if Rn == "1101" then SEE SUB (SP minus register);
10236      if (n == 13)
10237        return EmulateSUBSPReg(opcode, eEncodingT1);
10238
10239      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10240      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10241
10242      // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10243      // UNPREDICTABLE;
10244      if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10245          BadReg(m))
10246        return false;
10247
10248      break;
10249
10250    case eEncodingA1:
10251      // if Rn == '1101' then SEE SUB (SP minus register);
10252      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10253      d = Bits32(opcode, 15, 12);
10254      n = Bits32(opcode, 19, 16);
10255      m = Bits32(opcode, 3, 0);
10256      setflags = BitIsSet(opcode, 20);
10257
10258      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10259      // instructions;
10260      if ((d == 15) && setflags)
10261        EmulateSUBSPcLrEtc(opcode, encoding);
10262
10263      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10264      shift_n = DecodeImmShiftARM(opcode, shift_t);
10265
10266      break;
10267
10268    default:
10269      return false;
10270    }
10271
10272    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10273    uint32_t Rm = ReadCoreReg(m, &success);
10274    if (!success)
10275      return false;
10276
10277    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10278    if (!success)
10279      return false;
10280
10281    // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10282    uint32_t Rn = ReadCoreReg(n, &success);
10283    if (!success)
10284      return false;
10285
10286    AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10287
10288    // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10289    // // setflags is always FALSE here else
10290    // R[d] = result;
10291    // if setflags then
10292    // APSR.N = result<31>;
10293    // APSR.Z = IsZeroBit(result);
10294    // APSR.C = carry;
10295    // APSR.V = overflow;
10296
10297    EmulateInstruction::Context context;
10298    context.type = eContextArithmetic;
10299    std::optional<RegisterInfo> reg_n =
10300        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10301    std::optional<RegisterInfo> reg_m =
10302        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10303    context.SetRegisterRegisterOperands(*reg_n, *reg_m);
10304
10305    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10306                                   res.carry_out, res.overflow))
10307      return false;
10308  }
10309  return true;
10310}
10311
10312// A8.6.202 STREX
10313// Store Register Exclusive calculates an address from a base register value
10314// and an immediate offset, and stores a word from a register to memory if the
10315// executing processor has exclusive access to the memory addressed.
10316bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10317                                         const ARMEncoding encoding) {
10318#if 0
10319    if ConditionPassed() then
10320        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10321        address = R[n] + imm32;
10322        if ExclusiveMonitorsPass(address,4) then
10323            MemA[address,4] = R[t];
10324            R[d] = 0;
10325        else
10326            R[d] = 1;
10327#endif
10328
10329  bool success = false;
10330
10331  if (ConditionPassed(opcode)) {
10332    uint32_t d;
10333    uint32_t t;
10334    uint32_t n;
10335    uint32_t imm32;
10336    const uint32_t addr_byte_size = GetAddressByteSize();
10337
10338    switch (encoding) {
10339    case eEncodingT1:
10340      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10341      // ZeroExtend(imm8:'00',
10342      // 32);
10343      d = Bits32(opcode, 11, 8);
10344      t = Bits32(opcode, 15, 12);
10345      n = Bits32(opcode, 19, 16);
10346      imm32 = Bits32(opcode, 7, 0) << 2;
10347
10348      // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10349      if (BadReg(d) || BadReg(t) || (n == 15))
10350        return false;
10351
10352      // if d == n || d == t then UNPREDICTABLE;
10353      if ((d == n) || (d == t))
10354        return false;
10355
10356      break;
10357
10358    case eEncodingA1:
10359      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10360      // offset
10361      d = Bits32(opcode, 15, 12);
10362      t = Bits32(opcode, 3, 0);
10363      n = Bits32(opcode, 19, 16);
10364      imm32 = 0;
10365
10366      // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10367      if ((d == 15) || (t == 15) || (n == 15))
10368        return false;
10369
10370      // if d == n || d == t then UNPREDICTABLE;
10371      if ((d == n) || (d == t))
10372        return false;
10373
10374      break;
10375
10376    default:
10377      return false;
10378    }
10379
10380    // address = R[n] + imm32;
10381    uint32_t Rn = ReadCoreReg(n, &success);
10382    if (!success)
10383      return false;
10384
10385    addr_t address = Rn + imm32;
10386
10387    std::optional<RegisterInfo> base_reg =
10388        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10389    std::optional<RegisterInfo> data_reg =
10390        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10391    EmulateInstruction::Context context;
10392    context.type = eContextRegisterStore;
10393    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, imm32);
10394
10395    // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10396    // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10397    // will say this
10398    //                                                         always return
10399    //                                                         true.
10400    if (true) {
10401      // MemA[address,4] = R[t];
10402      uint32_t Rt =
10403          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10404      if (!success)
10405        return false;
10406
10407      if (!MemAWrite(context, address, Rt, addr_byte_size))
10408        return false;
10409
10410      // R[d] = 0;
10411      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10412        return false;
10413    }
10414#if 0  // unreachable because if true
10415        else
10416        {
10417            // R[d] = 1;
10418            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10419                return false;
10420        }
10421#endif // unreachable because if true
10422  }
10423  return true;
10424}
10425
10426// A8.6.197 STRB (immediate, ARM)
10427bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10428                                              const ARMEncoding encoding) {
10429#if 0
10430    if ConditionPassed() then
10431        EncodingSpecificOperations();
10432        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10433        address = if index then offset_addr else R[n];
10434        MemU[address,1] = R[t]<7:0>;
10435        if wback then R[n] = offset_addr;
10436#endif
10437
10438  bool success = false;
10439
10440  if (ConditionPassed(opcode)) {
10441    uint32_t t;
10442    uint32_t n;
10443    uint32_t imm32;
10444    bool index;
10445    bool add;
10446    bool wback;
10447
10448    switch (encoding) {
10449    case eEncodingA1:
10450      // if P == '0' && W == '1' then SEE STRBT;
10451      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10452      t = Bits32(opcode, 15, 12);
10453      n = Bits32(opcode, 19, 16);
10454      imm32 = Bits32(opcode, 11, 0);
10455
10456      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10457      index = BitIsSet(opcode, 24);
10458      add = BitIsSet(opcode, 23);
10459      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10460
10461      // if t == 15 then UNPREDICTABLE;
10462      if (t == 15)
10463        return false;
10464
10465      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10466      if (wback && ((n == 15) || (n == t)))
10467        return false;
10468
10469      break;
10470
10471    default:
10472      return false;
10473    }
10474
10475    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10476    uint32_t Rn = ReadCoreReg(n, &success);
10477    if (!success)
10478      return false;
10479
10480    addr_t offset_addr;
10481    if (add)
10482      offset_addr = Rn + imm32;
10483    else
10484      offset_addr = Rn - imm32;
10485
10486    // address = if index then offset_addr else R[n];
10487    addr_t address;
10488    if (index)
10489      address = offset_addr;
10490    else
10491      address = Rn;
10492
10493    // MemU[address,1] = R[t]<7:0>;
10494    uint32_t Rt = ReadCoreReg(t, &success);
10495    if (!success)
10496      return false;
10497
10498    std::optional<RegisterInfo> base_reg =
10499        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10500    std::optional<RegisterInfo> data_reg =
10501        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10502    EmulateInstruction::Context context;
10503    context.type = eContextRegisterStore;
10504    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
10505
10506    if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10507      return false;
10508
10509    // if wback then R[n] = offset_addr;
10510    if (wback) {
10511      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10512                                 offset_addr))
10513        return false;
10514    }
10515  }
10516  return true;
10517}
10518
10519// A8.6.194 STR (immediate, ARM)
10520bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10521                                             const ARMEncoding encoding) {
10522#if 0
10523    if ConditionPassed() then
10524        EncodingSpecificOperations();
10525        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10526        address = if index then offset_addr else R[n];
10527        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10528        if wback then R[n] = offset_addr;
10529#endif
10530
10531  bool success = false;
10532
10533  if (ConditionPassed(opcode)) {
10534    uint32_t t;
10535    uint32_t n;
10536    uint32_t imm32;
10537    bool index;
10538    bool add;
10539    bool wback;
10540
10541    const uint32_t addr_byte_size = GetAddressByteSize();
10542
10543    switch (encoding) {
10544    case eEncodingA1:
10545      // if P == '0' && W == '1' then SEE STRT;
10546      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10547      // '000000000100' then SEE PUSH;
10548      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10549      t = Bits32(opcode, 15, 12);
10550      n = Bits32(opcode, 19, 16);
10551      imm32 = Bits32(opcode, 11, 0);
10552
10553      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10554      index = BitIsSet(opcode, 24);
10555      add = BitIsSet(opcode, 23);
10556      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10557
10558      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10559      if (wback && ((n == 15) || (n == t)))
10560        return false;
10561
10562      break;
10563
10564    default:
10565      return false;
10566    }
10567
10568    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10569    uint32_t Rn = ReadCoreReg(n, &success);
10570    if (!success)
10571      return false;
10572
10573    addr_t offset_addr;
10574    if (add)
10575      offset_addr = Rn + imm32;
10576    else
10577      offset_addr = Rn - imm32;
10578
10579    // address = if index then offset_addr else R[n];
10580    addr_t address;
10581    if (index)
10582      address = offset_addr;
10583    else
10584      address = Rn;
10585
10586    std::optional<RegisterInfo> base_reg =
10587        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10588    std::optional<RegisterInfo> data_reg =
10589        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10590    EmulateInstruction::Context context;
10591    context.type = eContextRegisterStore;
10592    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
10593
10594    // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10595    uint32_t Rt = ReadCoreReg(t, &success);
10596    if (!success)
10597      return false;
10598
10599    if (t == 15) {
10600      uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10601      if (!success)
10602        return false;
10603
10604      if (!MemUWrite(context, address, pc_value, addr_byte_size))
10605        return false;
10606    } else {
10607      if (!MemUWrite(context, address, Rt, addr_byte_size))
10608        return false;
10609    }
10610
10611    // if wback then R[n] = offset_addr;
10612    if (wback) {
10613      context.type = eContextAdjustBaseRegister;
10614      context.SetImmediate(offset_addr);
10615
10616      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10617                                 offset_addr))
10618        return false;
10619    }
10620  }
10621  return true;
10622}
10623
10624// A8.6.66 LDRD (immediate)
10625// Load Register Dual (immediate) calculates an address from a base register
10626// value and an immediate offset, loads two words from memory, and writes them
10627// to two registers.  It can use offset, post-indexed, or pre-indexed
10628// addressing.
10629bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10630                                                 const ARMEncoding encoding) {
10631#if 0
10632    if ConditionPassed() then
10633        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10634        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10635        address = if index then offset_addr else R[n];
10636        R[t] = MemA[address,4];
10637        R[t2] = MemA[address+4,4];
10638        if wback then R[n] = offset_addr;
10639#endif
10640
10641  bool success = false;
10642
10643  if (ConditionPassed(opcode)) {
10644    uint32_t t;
10645    uint32_t t2;
10646    uint32_t n;
10647    uint32_t imm32;
10648    bool index;
10649    bool add;
10650    bool wback;
10651
10652    switch (encoding) {
10653    case eEncodingT1:
10654      // if P == '0' && W == '0' then SEE 'Related encodings';
10655      // if Rn == '1111' then SEE LDRD (literal);
10656      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10657      // ZeroExtend(imm8:'00', 32);
10658      t = Bits32(opcode, 15, 12);
10659      t2 = Bits32(opcode, 11, 8);
10660      n = Bits32(opcode, 19, 16);
10661      imm32 = Bits32(opcode, 7, 0) << 2;
10662
10663      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10664      index = BitIsSet(opcode, 24);
10665      add = BitIsSet(opcode, 23);
10666      wback = BitIsSet(opcode, 21);
10667
10668      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10669      if (wback && ((n == t) || (n == t2)))
10670        return false;
10671
10672      // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10673      if (BadReg(t) || BadReg(t2) || (t == t2))
10674        return false;
10675
10676      break;
10677
10678    case eEncodingA1:
10679      // if Rn == '1111' then SEE LDRD (literal);
10680      // if Rt<0> == '1' then UNPREDICTABLE;
10681      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10682      // 32);
10683      t = Bits32(opcode, 15, 12);
10684      if (BitIsSet(t, 0))
10685        return false;
10686      t2 = t + 1;
10687      n = Bits32(opcode, 19, 16);
10688      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10689
10690      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10691      index = BitIsSet(opcode, 24);
10692      add = BitIsSet(opcode, 23);
10693      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10694
10695      // if P == '0' && W == '1' then UNPREDICTABLE;
10696      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10697        return false;
10698
10699      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10700      if (wback && ((n == t) || (n == t2)))
10701        return false;
10702
10703      // if t2 == 15 then UNPREDICTABLE;
10704      if (t2 == 15)
10705        return false;
10706
10707      break;
10708
10709    default:
10710      return false;
10711    }
10712
10713    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10714    uint32_t Rn = ReadCoreReg(n, &success);
10715    if (!success)
10716      return false;
10717
10718    addr_t offset_addr;
10719    if (add)
10720      offset_addr = Rn + imm32;
10721    else
10722      offset_addr = Rn - imm32;
10723
10724    // address = if index then offset_addr else R[n];
10725    addr_t address;
10726    if (index)
10727      address = offset_addr;
10728    else
10729      address = Rn;
10730
10731    // R[t] = MemA[address,4];
10732
10733    EmulateInstruction::Context context;
10734    if (n == 13)
10735      context.type = eContextPopRegisterOffStack;
10736    else
10737      context.type = eContextRegisterLoad;
10738    context.SetAddress(address);
10739
10740    const uint32_t addr_byte_size = GetAddressByteSize();
10741    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10742    if (!success)
10743      return false;
10744
10745    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10746      return false;
10747
10748    // R[t2] = MemA[address+4,4];
10749    context.SetAddress(address + 4);
10750    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10751    if (!success)
10752      return false;
10753
10754    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10755                               data))
10756      return false;
10757
10758    // if wback then R[n] = offset_addr;
10759    if (wback) {
10760      context.type = eContextAdjustBaseRegister;
10761      context.SetAddress(offset_addr);
10762
10763      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10764                                 offset_addr))
10765        return false;
10766    }
10767  }
10768  return true;
10769}
10770
10771// A8.6.68 LDRD (register)
10772// Load Register Dual (register) calculates an address from a base register
10773// value and a register offset, loads two words from memory, and writes them to
10774// two registers.  It can use offset, post-indexed or pre-indexed addressing.
10775bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10776                                                const ARMEncoding encoding) {
10777#if 0
10778    if ConditionPassed() then
10779        EncodingSpecificOperations();
10780        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10781        address = if index then offset_addr else R[n];
10782        R[t] = MemA[address,4];
10783        R[t2] = MemA[address+4,4];
10784        if wback then R[n] = offset_addr;
10785#endif
10786
10787  bool success = false;
10788
10789  if (ConditionPassed(opcode)) {
10790    uint32_t t;
10791    uint32_t t2;
10792    uint32_t n;
10793    uint32_t m;
10794    bool index;
10795    bool add;
10796    bool wback;
10797
10798    switch (encoding) {
10799    case eEncodingA1:
10800      // if Rt<0> == '1' then UNPREDICTABLE;
10801      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10802      t = Bits32(opcode, 15, 12);
10803      if (BitIsSet(t, 0))
10804        return false;
10805      t2 = t + 1;
10806      n = Bits32(opcode, 19, 16);
10807      m = Bits32(opcode, 3, 0);
10808
10809      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10810      index = BitIsSet(opcode, 24);
10811      add = BitIsSet(opcode, 23);
10812      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10813
10814      // if P == '0' && W == '1' then UNPREDICTABLE;
10815      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10816        return false;
10817
10818      // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10819      if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10820        return false;
10821
10822      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10823      if (wback && ((n == 15) || (n == t) || (n == t2)))
10824        return false;
10825
10826      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10827      if ((ArchVersion() < 6) && wback && (m == n))
10828        return false;
10829      break;
10830
10831    default:
10832      return false;
10833    }
10834
10835    uint32_t Rn = ReadCoreReg(n, &success);
10836    if (!success)
10837      return false;
10838
10839    uint32_t Rm = ReadCoreReg(m, &success);
10840    if (!success)
10841      return false;
10842
10843    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10844    addr_t offset_addr;
10845    if (add)
10846      offset_addr = Rn + Rm;
10847    else
10848      offset_addr = Rn - Rm;
10849
10850    // address = if index then offset_addr else R[n];
10851    addr_t address;
10852    if (index)
10853      address = offset_addr;
10854    else
10855      address = Rn;
10856
10857    EmulateInstruction::Context context;
10858    if (n == 13)
10859      context.type = eContextPopRegisterOffStack;
10860    else
10861      context.type = eContextRegisterLoad;
10862    context.SetAddress(address);
10863
10864    // R[t] = MemA[address,4];
10865    const uint32_t addr_byte_size = GetAddressByteSize();
10866    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10867    if (!success)
10868      return false;
10869
10870    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10871      return false;
10872
10873    // R[t2] = MemA[address+4,4];
10874
10875    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10876    if (!success)
10877      return false;
10878
10879    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10880                               data))
10881      return false;
10882
10883    // if wback then R[n] = offset_addr;
10884    if (wback) {
10885      context.type = eContextAdjustBaseRegister;
10886      context.SetAddress(offset_addr);
10887
10888      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10889                                 offset_addr))
10890        return false;
10891    }
10892  }
10893  return true;
10894}
10895
10896// A8.6.200 STRD (immediate)
10897// Store Register Dual (immediate) calculates an address from a base register
10898// value and an immediate offset, and stores two words from two registers to
10899// memory.  It can use offset, post-indexed, or pre-indexed addressing.
10900bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10901                                           const ARMEncoding encoding) {
10902#if 0
10903    if ConditionPassed() then
10904        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10905        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10906        address = if index then offset_addr else R[n];
10907        MemA[address,4] = R[t];
10908        MemA[address+4,4] = R[t2];
10909        if wback then R[n] = offset_addr;
10910#endif
10911
10912  bool success = false;
10913
10914  if (ConditionPassed(opcode)) {
10915    uint32_t t;
10916    uint32_t t2;
10917    uint32_t n;
10918    uint32_t imm32;
10919    bool index;
10920    bool add;
10921    bool wback;
10922
10923    switch (encoding) {
10924    case eEncodingT1:
10925      // if P == '0' && W == '0' then SEE 'Related encodings';
10926      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10927      // ZeroExtend(imm8:'00', 32);
10928      t = Bits32(opcode, 15, 12);
10929      t2 = Bits32(opcode, 11, 8);
10930      n = Bits32(opcode, 19, 16);
10931      imm32 = Bits32(opcode, 7, 0) << 2;
10932
10933      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10934      index = BitIsSet(opcode, 24);
10935      add = BitIsSet(opcode, 23);
10936      wback = BitIsSet(opcode, 21);
10937
10938      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10939      if (wback && ((n == t) || (n == t2)))
10940        return false;
10941
10942      // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10943      if ((n == 15) || BadReg(t) || BadReg(t2))
10944        return false;
10945
10946      break;
10947
10948    case eEncodingA1:
10949      // if Rt<0> == '1' then UNPREDICTABLE;
10950      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10951      // 32);
10952      t = Bits32(opcode, 15, 12);
10953      if (BitIsSet(t, 0))
10954        return false;
10955
10956      t2 = t + 1;
10957      n = Bits32(opcode, 19, 16);
10958      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10959
10960      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10961      index = BitIsSet(opcode, 24);
10962      add = BitIsSet(opcode, 23);
10963      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10964
10965      // if P == '0' && W == '1' then UNPREDICTABLE;
10966      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10967        return false;
10968
10969      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10970      if (wback && ((n == 15) || (n == t) || (n == t2)))
10971        return false;
10972
10973      // if t2 == 15 then UNPREDICTABLE;
10974      if (t2 == 15)
10975        return false;
10976
10977      break;
10978
10979    default:
10980      return false;
10981    }
10982
10983    std::optional<RegisterInfo> base_reg =
10984        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10985
10986    uint32_t Rn = ReadCoreReg(n, &success);
10987    if (!success)
10988      return false;
10989
10990    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10991    addr_t offset_addr;
10992    if (add)
10993      offset_addr = Rn + imm32;
10994    else
10995      offset_addr = Rn - imm32;
10996
10997    // address = if index then offset_addr else R[n];
10998    addr_t address;
10999    if (index)
11000      address = offset_addr;
11001    else
11002      address = Rn;
11003
11004    // MemA[address,4] = R[t];
11005    std::optional<RegisterInfo> data_reg =
11006        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
11007
11008    uint32_t data = ReadCoreReg(t, &success);
11009    if (!success)
11010      return false;
11011
11012    EmulateInstruction::Context context;
11013    if (n == 13)
11014      context.type = eContextPushRegisterOnStack;
11015    else
11016      context.type = eContextRegisterStore;
11017    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
11018
11019    const uint32_t addr_byte_size = GetAddressByteSize();
11020
11021    if (!MemAWrite(context, address, data, addr_byte_size))
11022      return false;
11023
11024    // MemA[address+4,4] = R[t2];
11025    data_reg = GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2);
11026    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11027                                            (address + 4) - Rn);
11028
11029    data = ReadCoreReg(t2, &success);
11030    if (!success)
11031      return false;
11032
11033    if (!MemAWrite(context, address + 4, data, addr_byte_size))
11034      return false;
11035
11036    // if wback then R[n] = offset_addr;
11037    if (wback) {
11038      if (n == 13)
11039        context.type = eContextAdjustStackPointer;
11040      else
11041        context.type = eContextAdjustBaseRegister;
11042      context.SetAddress(offset_addr);
11043
11044      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11045                                 offset_addr))
11046        return false;
11047    }
11048  }
11049  return true;
11050}
11051
11052// A8.6.201 STRD (register)
11053bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11054                                           const ARMEncoding encoding) {
11055#if 0
11056    if ConditionPassed() then
11057        EncodingSpecificOperations();
11058        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11059        address = if index then offset_addr else R[n];
11060        MemA[address,4] = R[t];
11061        MemA[address+4,4] = R[t2];
11062        if wback then R[n] = offset_addr;
11063#endif
11064
11065  bool success = false;
11066
11067  if (ConditionPassed(opcode)) {
11068    uint32_t t;
11069    uint32_t t2;
11070    uint32_t n;
11071    uint32_t m;
11072    bool index;
11073    bool add;
11074    bool wback;
11075
11076    switch (encoding) {
11077    case eEncodingA1:
11078      // if Rt<0> == '1' then UNPREDICTABLE;
11079      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11080      t = Bits32(opcode, 15, 12);
11081      if (BitIsSet(t, 0))
11082        return false;
11083
11084      t2 = t + 1;
11085      n = Bits32(opcode, 19, 16);
11086      m = Bits32(opcode, 3, 0);
11087
11088      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11089      index = BitIsSet(opcode, 24);
11090      add = BitIsSet(opcode, 23);
11091      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11092
11093      // if P == '0' && W == '1' then UNPREDICTABLE;
11094      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11095        return false;
11096
11097      // if t2 == 15 || m == 15 then UNPREDICTABLE;
11098      if ((t2 == 15) || (m == 15))
11099        return false;
11100
11101      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11102      if (wback && ((n == 15) || (n == t) || (n == t2)))
11103        return false;
11104
11105      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11106      if ((ArchVersion() < 6) && wback && (m == n))
11107        return false;
11108
11109      break;
11110
11111    default:
11112      return false;
11113    }
11114
11115    uint32_t Rn = ReadCoreReg(n, &success);
11116    if (!success)
11117      return false;
11118
11119    uint32_t Rm = ReadCoreReg(m, &success);
11120    if (!success)
11121      return false;
11122
11123    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11124    addr_t offset_addr;
11125    if (add)
11126      offset_addr = Rn + Rm;
11127    else
11128      offset_addr = Rn - Rm;
11129
11130    // address = if index then offset_addr else R[n];
11131    addr_t address;
11132    if (index)
11133      address = offset_addr;
11134    else
11135      address = Rn;
11136    // MemA[address,4] = R[t];
11137    uint32_t Rt = ReadCoreReg(t, &success);
11138    if (!success)
11139      return false;
11140
11141    EmulateInstruction::Context context;
11142    if (t == 13)
11143      context.type = eContextPushRegisterOnStack;
11144    else
11145      context.type = eContextRegisterStore;
11146
11147    std::optional<RegisterInfo> base_reg =
11148        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11149    std::optional<RegisterInfo> offset_reg =
11150        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
11151    std::optional<RegisterInfo> data_reg =
11152        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
11153    context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
11154                                                    *data_reg);
11155
11156    const uint32_t addr_byte_size = GetAddressByteSize();
11157
11158    if (!MemAWrite(context, address, Rt, addr_byte_size))
11159      return false;
11160
11161    // MemA[address+4,4] = R[t2];
11162    uint32_t Rt2 = ReadCoreReg(t2, &success);
11163    if (!success)
11164      return false;
11165
11166    data_reg = GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2);
11167
11168    context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
11169                                                    *data_reg);
11170
11171    if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11172      return false;
11173
11174    // if wback then R[n] = offset_addr;
11175    if (wback) {
11176      context.type = eContextAdjustBaseRegister;
11177      context.SetAddress(offset_addr);
11178
11179      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11180                                 offset_addr))
11181        return false;
11182    }
11183  }
11184  return true;
11185}
11186
11187// A8.6.319 VLDM
11188// Vector Load Multiple loads multiple extension registers from consecutive
11189// memory locations using an address from an ARM core register.
11190bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11191                                        const ARMEncoding encoding) {
11192#if 0
11193    if ConditionPassed() then
11194        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11195        address = if add then R[n] else R[n]-imm32;
11196        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11197        for r = 0 to regs-1
11198            if single_regs then
11199                S[d+r] = MemA[address,4]; address = address+4;
11200            else
11201                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11202                // Combine the word-aligned words in the correct order for
11203                // current endianness.
11204                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11205#endif
11206
11207  bool success = false;
11208
11209  if (ConditionPassed(opcode)) {
11210    bool single_regs;
11211    bool add;
11212    bool wback;
11213    uint32_t d;
11214    uint32_t n;
11215    uint32_t imm32;
11216    uint32_t regs;
11217
11218    switch (encoding) {
11219    case eEncodingT1:
11220    case eEncodingA1:
11221      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11222      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11223      // if P == '1' && W == '0' then SEE VLDR;
11224      // if P == U && W == '1' then UNDEFINED;
11225      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11226        return false;
11227
11228      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11229      // !), 101 (DB with !)
11230      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11231      single_regs = false;
11232      add = BitIsSet(opcode, 23);
11233      wback = BitIsSet(opcode, 21);
11234
11235      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11236      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11237      n = Bits32(opcode, 19, 16);
11238      imm32 = Bits32(opcode, 7, 0) << 2;
11239
11240      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11241      regs = Bits32(opcode, 7, 0) / 2;
11242
11243      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11244      // UNPREDICTABLE;
11245      if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11246        return false;
11247
11248      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11249      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11250        return false;
11251
11252      break;
11253
11254    case eEncodingT2:
11255    case eEncodingA2:
11256      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11257      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11258      // if P == '1' && W == '0' then SEE VLDR;
11259      // if P == U && W == '1' then UNDEFINED;
11260      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11261        return false;
11262
11263      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11264      // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11265      // == '1'); d =
11266      // UInt(Vd:D); n = UInt(Rn);
11267      single_regs = true;
11268      add = BitIsSet(opcode, 23);
11269      wback = BitIsSet(opcode, 21);
11270      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11271      n = Bits32(opcode, 19, 16);
11272
11273      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11274      imm32 = Bits32(opcode, 7, 0) << 2;
11275      regs = Bits32(opcode, 7, 0);
11276
11277      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11278      // UNPREDICTABLE;
11279      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11280        return false;
11281
11282      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11283      if ((regs == 0) || ((d + regs) > 32))
11284        return false;
11285      break;
11286
11287    default:
11288      return false;
11289    }
11290
11291    uint32_t Rn = ReadCoreReg(n, &success);
11292    if (!success)
11293      return false;
11294
11295    // address = if add then R[n] else R[n]-imm32;
11296    addr_t address;
11297    if (add)
11298      address = Rn;
11299    else
11300      address = Rn - imm32;
11301
11302    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11303    EmulateInstruction::Context context;
11304
11305    if (wback) {
11306      uint32_t value;
11307      if (add)
11308        value = Rn + imm32;
11309      else
11310        value = Rn - imm32;
11311
11312      context.type = eContextAdjustBaseRegister;
11313      context.SetImmediateSigned(value - Rn);
11314      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11315                                 value))
11316        return false;
11317    }
11318
11319    const uint32_t addr_byte_size = GetAddressByteSize();
11320    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11321
11322    context.type = eContextRegisterLoad;
11323
11324    std::optional<RegisterInfo> base_reg =
11325        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11326
11327    // for r = 0 to regs-1
11328    for (uint32_t r = 0; r < regs; ++r) {
11329      if (single_regs) {
11330        // S[d+r] = MemA[address,4]; address = address+4;
11331        context.SetRegisterPlusOffset(*base_reg, address - Rn);
11332
11333        uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11334        if (!success)
11335          return false;
11336
11337        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11338                                   start_reg + d + r, data))
11339          return false;
11340
11341        address = address + 4;
11342      } else {
11343        // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11344        // address+8;
11345        context.SetRegisterPlusOffset(*base_reg, address - Rn);
11346        uint32_t word1 =
11347            MemARead(context, address, addr_byte_size, 0, &success);
11348        if (!success)
11349          return false;
11350
11351        context.SetRegisterPlusOffset(*base_reg, (address + 4) - Rn);
11352        uint32_t word2 =
11353            MemARead(context, address + 4, addr_byte_size, 0, &success);
11354        if (!success)
11355          return false;
11356
11357        address = address + 8;
11358        // // Combine the word-aligned words in the correct order for current
11359        // endianness.
11360        // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11361        uint64_t data;
11362        if (GetByteOrder() == eByteOrderBig) {
11363          data = word1;
11364          data = (data << 32) | word2;
11365        } else {
11366          data = word2;
11367          data = (data << 32) | word1;
11368        }
11369
11370        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11371                                   start_reg + d + r, data))
11372          return false;
11373      }
11374    }
11375  }
11376  return true;
11377}
11378
11379// A8.6.399 VSTM
11380// Vector Store Multiple stores multiple extension registers to consecutive
11381// memory locations using an address from an
11382// ARM core register.
11383bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11384                                        const ARMEncoding encoding) {
11385#if 0
11386    if ConditionPassed() then
11387        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11388        address = if add then R[n] else R[n]-imm32;
11389        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11390        for r = 0 to regs-1
11391            if single_regs then
11392                MemA[address,4] = S[d+r]; address = address+4;
11393            else
11394                // Store as two word-aligned words in the correct order for
11395                // current endianness.
11396                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11397                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11398                address = address+8;
11399#endif
11400
11401  bool success = false;
11402
11403  if (ConditionPassed(opcode)) {
11404    bool single_regs;
11405    bool add;
11406    bool wback;
11407    uint32_t d;
11408    uint32_t n;
11409    uint32_t imm32;
11410    uint32_t regs;
11411
11412    switch (encoding) {
11413    case eEncodingT1:
11414    case eEncodingA1:
11415      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11416      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11417      // if P == '1' && W == '0' then SEE VSTR;
11418      // if P == U && W == '1' then UNDEFINED;
11419      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11420        return false;
11421
11422      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11423      // !), 101 (DB with !)
11424      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11425      single_regs = false;
11426      add = BitIsSet(opcode, 23);
11427      wback = BitIsSet(opcode, 21);
11428
11429      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11430      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11431      n = Bits32(opcode, 19, 16);
11432      imm32 = Bits32(opcode, 7, 0) << 2;
11433
11434      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11435      regs = Bits32(opcode, 7, 0) / 2;
11436
11437      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11438      // UNPREDICTABLE;
11439      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11440        return false;
11441
11442      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11443      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11444        return false;
11445
11446      break;
11447
11448    case eEncodingT2:
11449    case eEncodingA2:
11450      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11451      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11452      // if P == '1' && W == '0' then SEE VSTR;
11453      // if P == U && W == '1' then UNDEFINED;
11454      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11455        return false;
11456
11457      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11458      // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11459      // == '1'); d =
11460      // UInt(Vd:D); n = UInt(Rn);
11461      single_regs = true;
11462      add = BitIsSet(opcode, 23);
11463      wback = BitIsSet(opcode, 21);
11464      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11465      n = Bits32(opcode, 19, 16);
11466
11467      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11468      imm32 = Bits32(opcode, 7, 0) << 2;
11469      regs = Bits32(opcode, 7, 0);
11470
11471      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11472      // UNPREDICTABLE;
11473      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11474        return false;
11475
11476      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11477      if ((regs == 0) || ((d + regs) > 32))
11478        return false;
11479
11480      break;
11481
11482    default:
11483      return false;
11484    }
11485
11486    std::optional<RegisterInfo> base_reg =
11487        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11488
11489    uint32_t Rn = ReadCoreReg(n, &success);
11490    if (!success)
11491      return false;
11492
11493    // address = if add then R[n] else R[n]-imm32;
11494    addr_t address;
11495    if (add)
11496      address = Rn;
11497    else
11498      address = Rn - imm32;
11499
11500    EmulateInstruction::Context context;
11501    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11502    if (wback) {
11503      uint32_t value;
11504      if (add)
11505        value = Rn + imm32;
11506      else
11507        value = Rn - imm32;
11508
11509      context.type = eContextAdjustBaseRegister;
11510      context.SetRegisterPlusOffset(*base_reg, value - Rn);
11511
11512      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11513                                 value))
11514        return false;
11515    }
11516
11517    const uint32_t addr_byte_size = GetAddressByteSize();
11518    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11519
11520    context.type = eContextRegisterStore;
11521    // for r = 0 to regs-1
11522    for (uint32_t r = 0; r < regs; ++r) {
11523
11524      if (single_regs) {
11525        // MemA[address,4] = S[d+r]; address = address+4;
11526        uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11527                                             start_reg + d + r, 0, &success);
11528        if (!success)
11529          return false;
11530
11531        std::optional<RegisterInfo> data_reg =
11532            GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r);
11533        context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11534                                                address - Rn);
11535        if (!MemAWrite(context, address, data, addr_byte_size))
11536          return false;
11537
11538        address = address + 4;
11539      } else {
11540        // // Store as two word-aligned words in the correct order for current
11541        // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11542        // D[d+r]<31:0>;
11543        // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11544        // D[d+r]<63:32>;
11545        uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11546                                             start_reg + d + r, 0, &success);
11547        if (!success)
11548          return false;
11549
11550        std::optional<RegisterInfo> data_reg =
11551            GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r);
11552
11553        if (GetByteOrder() == eByteOrderBig) {
11554          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11555                                                  address - Rn);
11556          if (!MemAWrite(context, address, Bits64(data, 63, 32),
11557                         addr_byte_size))
11558            return false;
11559
11560          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11561                                                  (address + 4) - Rn);
11562          if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11563                         addr_byte_size))
11564            return false;
11565        } else {
11566          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11567                                                  address - Rn);
11568          if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11569            return false;
11570
11571          context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11572                                                  (address + 4) - Rn);
11573          if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11574                         addr_byte_size))
11575            return false;
11576        }
11577        // address = address+8;
11578        address = address + 8;
11579      }
11580    }
11581  }
11582  return true;
11583}
11584
11585// A8.6.320
11586// This instruction loads a single extension register from memory, using an
11587// address from an ARM core register, with an optional offset.
11588bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11589                                        ARMEncoding encoding) {
11590#if 0
11591    if ConditionPassed() then
11592        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11593        base = if n == 15 then Align(PC,4) else R[n];
11594        address = if add then (base + imm32) else (base - imm32);
11595        if single_reg then
11596            S[d] = MemA[address,4];
11597        else
11598            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11599            // Combine the word-aligned words in the correct order for current
11600            // endianness.
11601            D[d] = if BigEndian() then word1:word2 else word2:word1;
11602#endif
11603
11604  bool success = false;
11605
11606  if (ConditionPassed(opcode)) {
11607    bool single_reg;
11608    bool add;
11609    uint32_t imm32;
11610    uint32_t d;
11611    uint32_t n;
11612
11613    switch (encoding) {
11614    case eEncodingT1:
11615    case eEncodingA1:
11616      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11617      // 32);
11618      single_reg = false;
11619      add = BitIsSet(opcode, 23);
11620      imm32 = Bits32(opcode, 7, 0) << 2;
11621
11622      // d = UInt(D:Vd); n = UInt(Rn);
11623      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11624      n = Bits32(opcode, 19, 16);
11625
11626      break;
11627
11628    case eEncodingT2:
11629    case eEncodingA2:
11630      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11631      single_reg = true;
11632      add = BitIsSet(opcode, 23);
11633      imm32 = Bits32(opcode, 7, 0) << 2;
11634
11635      // d = UInt(Vd:D); n = UInt(Rn);
11636      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11637      n = Bits32(opcode, 19, 16);
11638
11639      break;
11640
11641    default:
11642      return false;
11643    }
11644    std::optional<RegisterInfo> base_reg =
11645        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11646
11647    uint32_t Rn = ReadCoreReg(n, &success);
11648    if (!success)
11649      return false;
11650
11651    // base = if n == 15 then Align(PC,4) else R[n];
11652    uint32_t base;
11653    if (n == 15)
11654      base = AlignPC(Rn);
11655    else
11656      base = Rn;
11657
11658    // address = if add then (base + imm32) else (base - imm32);
11659    addr_t address;
11660    if (add)
11661      address = base + imm32;
11662    else
11663      address = base - imm32;
11664
11665    const uint32_t addr_byte_size = GetAddressByteSize();
11666    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11667
11668    EmulateInstruction::Context context;
11669    context.type = eContextRegisterLoad;
11670    context.SetRegisterPlusOffset(*base_reg, address - base);
11671
11672    if (single_reg) {
11673      // S[d] = MemA[address,4];
11674      uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11675      if (!success)
11676        return false;
11677
11678      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11679                                 data))
11680        return false;
11681    } else {
11682      // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11683      uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11684      if (!success)
11685        return false;
11686
11687      context.SetRegisterPlusOffset(*base_reg, (address + 4) - base);
11688      uint32_t word2 =
11689          MemARead(context, address + 4, addr_byte_size, 0, &success);
11690      if (!success)
11691        return false;
11692      // // Combine the word-aligned words in the correct order for current
11693      // endianness.
11694      // D[d] = if BigEndian() then word1:word2 else word2:word1;
11695      uint64_t data64;
11696      if (GetByteOrder() == eByteOrderBig) {
11697        data64 = word1;
11698        data64 = (data64 << 32) | word2;
11699      } else {
11700        data64 = word2;
11701        data64 = (data64 << 32) | word1;
11702      }
11703
11704      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11705                                 data64))
11706        return false;
11707    }
11708  }
11709  return true;
11710}
11711
11712// A8.6.400 VSTR
11713// This instruction stores a signle extension register to memory, using an
11714// address from an ARM core register, with an optional offset.
11715bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11716                                        ARMEncoding encoding) {
11717#if 0
11718    if ConditionPassed() then
11719        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11720        address = if add then (R[n] + imm32) else (R[n] - imm32);
11721        if single_reg then
11722            MemA[address,4] = S[d];
11723        else
11724            // Store as two word-aligned words in the correct order for current
11725            // endianness.
11726            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11727            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11728#endif
11729
11730  bool success = false;
11731
11732  if (ConditionPassed(opcode)) {
11733    bool single_reg;
11734    bool add;
11735    uint32_t imm32;
11736    uint32_t d;
11737    uint32_t n;
11738
11739    switch (encoding) {
11740    case eEncodingT1:
11741    case eEncodingA1:
11742      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11743      // 32);
11744      single_reg = false;
11745      add = BitIsSet(opcode, 23);
11746      imm32 = Bits32(opcode, 7, 0) << 2;
11747
11748      // d = UInt(D:Vd); n = UInt(Rn);
11749      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11750      n = Bits32(opcode, 19, 16);
11751
11752      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11753      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11754        return false;
11755
11756      break;
11757
11758    case eEncodingT2:
11759    case eEncodingA2:
11760      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11761      single_reg = true;
11762      add = BitIsSet(opcode, 23);
11763      imm32 = Bits32(opcode, 7, 0) << 2;
11764
11765      // d = UInt(Vd:D); n = UInt(Rn);
11766      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11767      n = Bits32(opcode, 19, 16);
11768
11769      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11770      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11771        return false;
11772
11773      break;
11774
11775    default:
11776      return false;
11777    }
11778
11779    uint32_t Rn = ReadCoreReg(n, &success);
11780    if (!success)
11781      return false;
11782
11783    // address = if add then (R[n] + imm32) else (R[n] - imm32);
11784    addr_t address;
11785    if (add)
11786      address = Rn + imm32;
11787    else
11788      address = Rn - imm32;
11789
11790    const uint32_t addr_byte_size = GetAddressByteSize();
11791    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11792
11793    std::optional<RegisterInfo> base_reg =
11794        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11795    std::optional<RegisterInfo> data_reg =
11796        GetRegisterInfo(eRegisterKindDWARF, start_reg + d);
11797    EmulateInstruction::Context context;
11798    context.type = eContextRegisterStore;
11799    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
11800
11801    if (single_reg) {
11802      // MemA[address,4] = S[d];
11803      uint32_t data =
11804          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11805      if (!success)
11806        return false;
11807
11808      if (!MemAWrite(context, address, data, addr_byte_size))
11809        return false;
11810    } else {
11811      // // Store as two word-aligned words in the correct order for current
11812      // endianness.
11813      // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11814      // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11815      uint64_t data =
11816          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11817      if (!success)
11818        return false;
11819
11820      if (GetByteOrder() == eByteOrderBig) {
11821        if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11822          return false;
11823
11824        context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11825                                                (address + 4) - Rn);
11826        if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11827                       addr_byte_size))
11828          return false;
11829      } else {
11830        if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11831          return false;
11832
11833        context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11834                                                (address + 4) - Rn);
11835        if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11836                       addr_byte_size))
11837          return false;
11838      }
11839    }
11840  }
11841  return true;
11842}
11843
11844// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11845// from memory into one, two, three or four registers, without de-interleaving.
11846// Every element of each register is loaded.
11847bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11848                                                ARMEncoding encoding) {
11849#if 0
11850    if ConditionPassed() then
11851        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11852        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11853        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11854        for r = 0 to regs-1
11855            for e = 0 to elements-1
11856                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11857                address = address + ebytes;
11858#endif
11859
11860  bool success = false;
11861
11862  if (ConditionPassed(opcode)) {
11863    uint32_t regs;
11864    uint32_t alignment;
11865    uint32_t ebytes;
11866    uint32_t esize;
11867    uint32_t elements;
11868    uint32_t d;
11869    uint32_t n;
11870    uint32_t m;
11871    bool wback;
11872    bool register_index;
11873
11874    switch (encoding) {
11875    case eEncodingT1:
11876    case eEncodingA1: {
11877      // case type of
11878      // when '0111'
11879      // regs = 1; if align<1> == '1' then UNDEFINED;
11880      // when '1010'
11881      // regs = 2; if align == '11' then UNDEFINED;
11882      // when '0110'
11883      // regs = 3; if align<1> == '1' then UNDEFINED;
11884      // when '0010'
11885      // regs = 4;
11886      // otherwise
11887      // SEE 'Related encodings';
11888      uint32_t type = Bits32(opcode, 11, 8);
11889      uint32_t align = Bits32(opcode, 5, 4);
11890      if (type == 7) // '0111'
11891      {
11892        regs = 1;
11893        if (BitIsSet(align, 1))
11894          return false;
11895      } else if (type == 10) // '1010'
11896      {
11897        regs = 2;
11898        if (align == 3)
11899          return false;
11900
11901      } else if (type == 6) // '0110'
11902      {
11903        regs = 3;
11904        if (BitIsSet(align, 1))
11905          return false;
11906      } else if (type == 2) // '0010'
11907      {
11908        regs = 4;
11909      } else
11910        return false;
11911
11912      // alignment = if align == '00' then 1 else 4 << UInt(align);
11913      if (align == 0)
11914        alignment = 1;
11915      else
11916        alignment = 4 << align;
11917
11918      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11919      ebytes = 1 << Bits32(opcode, 7, 6);
11920      esize = 8 * ebytes;
11921      elements = 8 / ebytes;
11922
11923      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11924      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11925      n = Bits32(opcode, 19, 15);
11926      m = Bits32(opcode, 3, 0);
11927
11928      // wback = (m != 15); register_index = (m != 15 && m != 13);
11929      wback = (m != 15);
11930      register_index = ((m != 15) && (m != 13));
11931
11932      // if d+regs > 32 then UNPREDICTABLE;
11933      if ((d + regs) > 32)
11934        return false;
11935    } break;
11936
11937    default:
11938      return false;
11939    }
11940
11941    std::optional<RegisterInfo> base_reg =
11942        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11943
11944    uint32_t Rn = ReadCoreReg(n, &success);
11945    if (!success)
11946      return false;
11947
11948    // address = R[n]; if (address MOD alignment) != 0 then
11949    // GenerateAlignmentException();
11950    addr_t address = Rn;
11951    if ((address % alignment) != 0)
11952      return false;
11953
11954    EmulateInstruction::Context context;
11955    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11956    if (wback) {
11957      uint32_t Rm = ReadCoreReg(m, &success);
11958      if (!success)
11959        return false;
11960
11961      uint32_t offset;
11962      if (register_index)
11963        offset = Rm;
11964      else
11965        offset = 8 * regs;
11966
11967      uint32_t value = Rn + offset;
11968      context.type = eContextAdjustBaseRegister;
11969      context.SetRegisterPlusOffset(*base_reg, offset);
11970
11971      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11972                                 value))
11973        return false;
11974    }
11975
11976    // for r = 0 to regs-1
11977    for (uint32_t r = 0; r < regs; ++r) {
11978      // for e = 0 to elements-1
11979      uint64_t assembled_data = 0;
11980      for (uint32_t e = 0; e < elements; ++e) {
11981        // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11982        context.type = eContextRegisterLoad;
11983        context.SetRegisterPlusOffset(*base_reg, address - Rn);
11984        uint64_t data = MemURead(context, address, ebytes, 0, &success);
11985        if (!success)
11986          return false;
11987
11988        assembled_data =
11989            (data << (e * esize)) |
11990            assembled_data; // New data goes to the left of existing data
11991
11992        // address = address + ebytes;
11993        address = address + ebytes;
11994      }
11995      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
11996                                 assembled_data))
11997        return false;
11998    }
11999  }
12000  return true;
12001}
12002
12003// A8.6.308 VLD1 (single element to one lane)
12004//
12005bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12006                                              const ARMEncoding encoding) {
12007#if 0
12008    if ConditionPassed() then
12009        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12010        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12011        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12012        Elem[D[d],index,esize] = MemU[address,ebytes];
12013#endif
12014
12015  bool success = false;
12016
12017  if (ConditionPassed(opcode)) {
12018    uint32_t ebytes;
12019    uint32_t esize;
12020    uint32_t index;
12021    uint32_t alignment;
12022    uint32_t d;
12023    uint32_t n;
12024    uint32_t m;
12025    bool wback;
12026    bool register_index;
12027
12028    switch (encoding) {
12029    case eEncodingT1:
12030    case eEncodingA1: {
12031      uint32_t size = Bits32(opcode, 11, 10);
12032      uint32_t index_align = Bits32(opcode, 7, 4);
12033      // if size == '11' then SEE VLD1 (single element to all lanes);
12034      if (size == 3)
12035        return EmulateVLD1SingleAll(opcode, encoding);
12036      // case size of
12037      if (size == 0) // when '00'
12038      {
12039        // if index_align<0> != '0' then UNDEFINED;
12040        if (BitIsClear(index_align, 0))
12041          return false;
12042
12043        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12044        ebytes = 1;
12045        esize = 8;
12046        index = Bits32(index_align, 3, 1);
12047        alignment = 1;
12048      } else if (size == 1) // when '01'
12049      {
12050        // if index_align<1> != '0' then UNDEFINED;
12051        if (BitIsClear(index_align, 1))
12052          return false;
12053
12054        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12055        ebytes = 2;
12056        esize = 16;
12057        index = Bits32(index_align, 3, 2);
12058
12059        // alignment = if index_align<0> == '0' then 1 else 2;
12060        if (BitIsClear(index_align, 0))
12061          alignment = 1;
12062        else
12063          alignment = 2;
12064      } else if (size == 2) // when '10'
12065      {
12066        // if index_align<2> != '0' then UNDEFINED;
12067        if (BitIsClear(index_align, 2))
12068          return false;
12069
12070        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12071        // UNDEFINED;
12072        if ((Bits32(index_align, 1, 0) != 0) &&
12073            (Bits32(index_align, 1, 0) != 3))
12074          return false;
12075
12076        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12077        ebytes = 4;
12078        esize = 32;
12079        index = Bit32(index_align, 3);
12080
12081        // alignment = if index_align<1:0> == '00' then 1 else 4;
12082        if (Bits32(index_align, 1, 0) == 0)
12083          alignment = 1;
12084        else
12085          alignment = 4;
12086      } else {
12087        return false;
12088      }
12089      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12090      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12091      n = Bits32(opcode, 19, 16);
12092      m = Bits32(opcode, 3, 0);
12093
12094      // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12095      // then UNPREDICTABLE;
12096      wback = (m != 15);
12097      register_index = ((m != 15) && (m != 13));
12098
12099      if (n == 15)
12100        return false;
12101
12102    } break;
12103
12104    default:
12105      return false;
12106    }
12107
12108    uint32_t Rn = ReadCoreReg(n, &success);
12109    if (!success)
12110      return false;
12111
12112    // address = R[n]; if (address MOD alignment) != 0 then
12113    // GenerateAlignmentException();
12114    addr_t address = Rn;
12115    if ((address % alignment) != 0)
12116      return false;
12117
12118    EmulateInstruction::Context context;
12119    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12120    if (wback) {
12121      uint32_t Rm = ReadCoreReg(m, &success);
12122      if (!success)
12123        return false;
12124
12125      uint32_t offset;
12126      if (register_index)
12127        offset = Rm;
12128      else
12129        offset = ebytes;
12130
12131      uint32_t value = Rn + offset;
12132
12133      context.type = eContextAdjustBaseRegister;
12134      std::optional<RegisterInfo> base_reg =
12135          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12136      context.SetRegisterPlusOffset(*base_reg, offset);
12137
12138      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12139                                 value))
12140        return false;
12141    }
12142
12143    // Elem[D[d],index,esize] = MemU[address,ebytes];
12144    uint32_t element = MemURead(context, address, esize, 0, &success);
12145    if (!success)
12146      return false;
12147
12148    element = element << (index * esize);
12149
12150    uint64_t reg_data =
12151        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12152    if (!success)
12153      return false;
12154
12155    uint64_t all_ones = -1;
12156    uint64_t mask = all_ones
12157                    << ((index + 1) * esize); // mask is all 1's to left of
12158                                              // where 'element' goes, & all 0's
12159    // at element & to the right of element.
12160    if (index > 0)
12161      mask = mask | Bits64(all_ones, (index * esize) - 1,
12162                           0); // add 1's to the right of where 'element' goes.
12163    // now mask should be 0's where element goes & 1's everywhere else.
12164
12165    uint64_t masked_reg =
12166        reg_data & mask; // Take original reg value & zero out 'element' bits
12167    reg_data =
12168        masked_reg & element; // Put 'element' into those bits in reg_data.
12169
12170    context.type = eContextRegisterLoad;
12171    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12172                               reg_data))
12173      return false;
12174  }
12175  return true;
12176}
12177
12178// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12179// elements) stores elements to memory from one, two, three, or four registers,
12180// without interleaving.  Every element of each register is stored.
12181bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12182                                                ARMEncoding encoding) {
12183#if 0
12184    if ConditionPassed() then
12185        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12186        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12187        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12188        for r = 0 to regs-1
12189            for e = 0 to elements-1
12190                MemU[address,ebytes] = Elem[D[d+r],e,esize];
12191                address = address + ebytes;
12192#endif
12193
12194  bool success = false;
12195
12196  if (ConditionPassed(opcode)) {
12197    uint32_t regs;
12198    uint32_t alignment;
12199    uint32_t ebytes;
12200    uint32_t esize;
12201    uint32_t elements;
12202    uint32_t d;
12203    uint32_t n;
12204    uint32_t m;
12205    bool wback;
12206    bool register_index;
12207
12208    switch (encoding) {
12209    case eEncodingT1:
12210    case eEncodingA1: {
12211      uint32_t type = Bits32(opcode, 11, 8);
12212      uint32_t align = Bits32(opcode, 5, 4);
12213
12214      // case type of
12215      if (type == 7) // when '0111'
12216      {
12217        // regs = 1; if align<1> == '1' then UNDEFINED;
12218        regs = 1;
12219        if (BitIsSet(align, 1))
12220          return false;
12221      } else if (type == 10) // when '1010'
12222      {
12223        // regs = 2; if align == '11' then UNDEFINED;
12224        regs = 2;
12225        if (align == 3)
12226          return false;
12227      } else if (type == 6) // when '0110'
12228      {
12229        // regs = 3; if align<1> == '1' then UNDEFINED;
12230        regs = 3;
12231        if (BitIsSet(align, 1))
12232          return false;
12233      } else if (type == 2) // when '0010'
12234        // regs = 4;
12235        regs = 4;
12236      else // otherwise
12237        // SEE 'Related encodings';
12238        return false;
12239
12240      // alignment = if align == '00' then 1 else 4 << UInt(align);
12241      if (align == 0)
12242        alignment = 1;
12243      else
12244        alignment = 4 << align;
12245
12246      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12247      ebytes = 1 << Bits32(opcode, 7, 6);
12248      esize = 8 * ebytes;
12249      elements = 8 / ebytes;
12250
12251      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12252      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12253      n = Bits32(opcode, 19, 16);
12254      m = Bits32(opcode, 3, 0);
12255
12256      // wback = (m != 15); register_index = (m != 15 && m != 13);
12257      wback = (m != 15);
12258      register_index = ((m != 15) && (m != 13));
12259
12260      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12261      if ((d + regs) > 32)
12262        return false;
12263
12264      if (n == 15)
12265        return false;
12266
12267    } break;
12268
12269    default:
12270      return false;
12271    }
12272
12273    std::optional<RegisterInfo> base_reg =
12274        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12275
12276    uint32_t Rn = ReadCoreReg(n, &success);
12277    if (!success)
12278      return false;
12279
12280    // address = R[n]; if (address MOD alignment) != 0 then
12281    // GenerateAlignmentException();
12282    addr_t address = Rn;
12283    if ((address % alignment) != 0)
12284      return false;
12285
12286    EmulateInstruction::Context context;
12287    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12288    if (wback) {
12289      uint32_t Rm = ReadCoreReg(m, &success);
12290      if (!success)
12291        return false;
12292
12293      uint32_t offset;
12294      if (register_index)
12295        offset = Rm;
12296      else
12297        offset = 8 * regs;
12298
12299      context.type = eContextAdjustBaseRegister;
12300      context.SetRegisterPlusOffset(*base_reg, offset);
12301
12302      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12303                                 Rn + offset))
12304        return false;
12305    }
12306
12307    context.type = eContextRegisterStore;
12308    // for r = 0 to regs-1
12309    for (uint32_t r = 0; r < regs; ++r) {
12310      std::optional<RegisterInfo> data_reg =
12311          GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r);
12312      uint64_t register_data = ReadRegisterUnsigned(
12313          eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12314      if (!success)
12315        return false;
12316
12317      // for e = 0 to elements-1
12318      for (uint32_t e = 0; e < elements; ++e) {
12319        // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12320        uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12321
12322        context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
12323                                                address - Rn);
12324        if (!MemUWrite(context, address, word, ebytes))
12325          return false;
12326
12327        // address = address + ebytes;
12328        address = address + ebytes;
12329      }
12330    }
12331  }
12332  return true;
12333}
12334
12335// A8.6.392 VST1 (single element from one lane) This instruction stores one
12336// element to memory from one element of a register.
12337bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12338                                              ARMEncoding encoding) {
12339#if 0
12340    if ConditionPassed() then
12341        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12342        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12343        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12344        MemU[address,ebytes] = Elem[D[d],index,esize];
12345#endif
12346
12347  bool success = false;
12348
12349  if (ConditionPassed(opcode)) {
12350    uint32_t ebytes;
12351    uint32_t esize;
12352    uint32_t index;
12353    uint32_t alignment;
12354    uint32_t d;
12355    uint32_t n;
12356    uint32_t m;
12357    bool wback;
12358    bool register_index;
12359
12360    switch (encoding) {
12361    case eEncodingT1:
12362    case eEncodingA1: {
12363      uint32_t size = Bits32(opcode, 11, 10);
12364      uint32_t index_align = Bits32(opcode, 7, 4);
12365
12366      // if size == '11' then UNDEFINED;
12367      if (size == 3)
12368        return false;
12369
12370      // case size of
12371      if (size == 0) // when '00'
12372      {
12373        // if index_align<0> != '0' then UNDEFINED;
12374        if (BitIsClear(index_align, 0))
12375          return false;
12376        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12377        ebytes = 1;
12378        esize = 8;
12379        index = Bits32(index_align, 3, 1);
12380        alignment = 1;
12381      } else if (size == 1) // when '01'
12382      {
12383        // if index_align<1> != '0' then UNDEFINED;
12384        if (BitIsClear(index_align, 1))
12385          return false;
12386
12387        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12388        ebytes = 2;
12389        esize = 16;
12390        index = Bits32(index_align, 3, 2);
12391
12392        // alignment = if index_align<0> == '0' then 1 else 2;
12393        if (BitIsClear(index_align, 0))
12394          alignment = 1;
12395        else
12396          alignment = 2;
12397      } else if (size == 2) // when '10'
12398      {
12399        // if index_align<2> != '0' then UNDEFINED;
12400        if (BitIsClear(index_align, 2))
12401          return false;
12402
12403        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12404        // UNDEFINED;
12405        if ((Bits32(index_align, 1, 0) != 0) &&
12406            (Bits32(index_align, 1, 0) != 3))
12407          return false;
12408
12409        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12410        ebytes = 4;
12411        esize = 32;
12412        index = Bit32(index_align, 3);
12413
12414        // alignment = if index_align<1:0> == '00' then 1 else 4;
12415        if (Bits32(index_align, 1, 0) == 0)
12416          alignment = 1;
12417        else
12418          alignment = 4;
12419      } else {
12420        return false;
12421      }
12422      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12423      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12424      n = Bits32(opcode, 19, 16);
12425      m = Bits32(opcode, 3, 0);
12426
12427      // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12428      // then UNPREDICTABLE;
12429      wback = (m != 15);
12430      register_index = ((m != 15) && (m != 13));
12431
12432      if (n == 15)
12433        return false;
12434    } break;
12435
12436    default:
12437      return false;
12438    }
12439
12440    std::optional<RegisterInfo> base_reg =
12441        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12442
12443    uint32_t Rn = ReadCoreReg(n, &success);
12444    if (!success)
12445      return false;
12446
12447    // address = R[n]; if (address MOD alignment) != 0 then
12448    // GenerateAlignmentException();
12449    addr_t address = Rn;
12450    if ((address % alignment) != 0)
12451      return false;
12452
12453    EmulateInstruction::Context context;
12454    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12455    if (wback) {
12456      uint32_t Rm = ReadCoreReg(m, &success);
12457      if (!success)
12458        return false;
12459
12460      uint32_t offset;
12461      if (register_index)
12462        offset = Rm;
12463      else
12464        offset = ebytes;
12465
12466      context.type = eContextAdjustBaseRegister;
12467      context.SetRegisterPlusOffset(*base_reg, offset);
12468
12469      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12470                                 Rn + offset))
12471        return false;
12472    }
12473
12474    // MemU[address,ebytes] = Elem[D[d],index,esize];
12475    uint64_t register_data =
12476        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12477    if (!success)
12478      return false;
12479
12480    uint64_t word =
12481        Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12482
12483    std::optional<RegisterInfo> data_reg =
12484        GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d);
12485    context.type = eContextRegisterStore;
12486    context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
12487
12488    if (!MemUWrite(context, address, word, ebytes))
12489      return false;
12490  }
12491  return true;
12492}
12493
12494// A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12495// element from memory into every element of one or two vectors.
12496bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12497                                                 const ARMEncoding encoding) {
12498#if 0
12499    if ConditionPassed() then
12500        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12501        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12502        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12503        replicated_element = Replicate(MemU[address,ebytes], elements);
12504        for r = 0 to regs-1
12505            D[d+r] = replicated_element;
12506#endif
12507
12508  bool success = false;
12509
12510  if (ConditionPassed(opcode)) {
12511    uint32_t ebytes;
12512    uint32_t elements;
12513    uint32_t regs;
12514    uint32_t alignment;
12515    uint32_t d;
12516    uint32_t n;
12517    uint32_t m;
12518    bool wback;
12519    bool register_index;
12520
12521    switch (encoding) {
12522    case eEncodingT1:
12523    case eEncodingA1: {
12524      // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12525      uint32_t size = Bits32(opcode, 7, 6);
12526      if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12527        return false;
12528
12529      // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12530      // then 1 else 2;
12531      ebytes = 1 << size;
12532      elements = 8 / ebytes;
12533      if (BitIsClear(opcode, 5))
12534        regs = 1;
12535      else
12536        regs = 2;
12537
12538      // alignment = if a == '0' then 1 else ebytes;
12539      if (BitIsClear(opcode, 4))
12540        alignment = 1;
12541      else
12542        alignment = ebytes;
12543
12544      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12545      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12546      n = Bits32(opcode, 19, 16);
12547      m = Bits32(opcode, 3, 0);
12548
12549      // wback = (m != 15); register_index = (m != 15 && m != 13);
12550      wback = (m != 15);
12551      register_index = ((m != 15) && (m != 13));
12552
12553      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12554      if ((d + regs) > 32)
12555        return false;
12556
12557      if (n == 15)
12558        return false;
12559    } break;
12560
12561    default:
12562      return false;
12563    }
12564
12565    uint32_t Rn = ReadCoreReg(n, &success);
12566    if (!success)
12567      return false;
12568
12569    // address = R[n]; if (address MOD alignment) != 0 then
12570    // GenerateAlignmentException();
12571    addr_t address = Rn;
12572    if ((address % alignment) != 0)
12573      return false;
12574
12575    EmulateInstruction::Context context;
12576    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12577    if (wback) {
12578      uint32_t Rm = ReadCoreReg(m, &success);
12579      if (!success)
12580        return false;
12581
12582      uint32_t offset;
12583      if (register_index)
12584        offset = Rm;
12585      else
12586        offset = ebytes;
12587
12588      context.type = eContextAdjustBaseRegister;
12589      std::optional<RegisterInfo> base_reg =
12590          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12591      context.SetRegisterPlusOffset(*base_reg, offset);
12592
12593      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12594                                 Rn + offset))
12595        return false;
12596    }
12597
12598    // replicated_element = Replicate(MemU[address,ebytes], elements);
12599
12600    context.type = eContextRegisterLoad;
12601    uint64_t word = MemURead(context, address, ebytes, 0, &success);
12602    if (!success)
12603      return false;
12604
12605    uint64_t replicated_element = 0;
12606    uint32_t esize = ebytes * 8;
12607    for (uint32_t e = 0; e < elements; ++e)
12608      replicated_element =
12609          (replicated_element << esize) | Bits64(word, esize - 1, 0);
12610
12611    // for r = 0 to regs-1
12612    for (uint32_t r = 0; r < regs; ++r) {
12613      // D[d+r] = replicated_element;
12614      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12615                                 replicated_element))
12616        return false;
12617    }
12618  }
12619  return true;
12620}
12621
12622// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12623// instruction provides an exception return without the use of the stack.  It
12624// subtracts the immediate constant from the LR, branches to the resulting
12625// address, and also copies the SPSR to the CPSR.
12626bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12627                                               const ARMEncoding encoding) {
12628#if 0
12629    if ConditionPassed() then
12630        EncodingSpecificOperations();
12631        if CurrentInstrSet() == InstrSet_ThumbEE then
12632            UNPREDICTABLE;
12633        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12634        case opcode of
12635            when '0000' result = R[n] AND operand2; // AND
12636            when '0001' result = R[n] EOR operand2; // EOR
12637            when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12638            when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12639            when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12640            when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12641            when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12642            when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12643            when '1100' result = R[n] OR operand2; // ORR
12644            when '1101' result = operand2; // MOV
12645            when '1110' result = R[n] AND NOT(operand2); // BIC
12646            when '1111' result = NOT(operand2); // MVN
12647        CPSRWriteByInstr(SPSR[], '1111', TRUE);
12648        BranchWritePC(result);
12649#endif
12650
12651  bool success = false;
12652
12653  if (ConditionPassed(opcode)) {
12654    uint32_t n;
12655    uint32_t m;
12656    uint32_t imm32;
12657    bool register_form;
12658    ARM_ShifterType shift_t;
12659    uint32_t shift_n;
12660    uint32_t code;
12661
12662    switch (encoding) {
12663    case eEncodingT1:
12664      // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12665      // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12666      // // = SUB
12667      n = 14;
12668      imm32 = Bits32(opcode, 7, 0);
12669      register_form = false;
12670      code = 2;
12671
12672      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12673      if (InITBlock() && !LastInITBlock())
12674        return false;
12675
12676      break;
12677
12678    case eEncodingA1:
12679      // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12680      n = Bits32(opcode, 19, 16);
12681      imm32 = ARMExpandImm(opcode);
12682      register_form = false;
12683      code = Bits32(opcode, 24, 21);
12684
12685      break;
12686
12687    case eEncodingA2:
12688      // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12689      n = Bits32(opcode, 19, 16);
12690      m = Bits32(opcode, 3, 0);
12691      register_form = true;
12692
12693      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12694      shift_n = DecodeImmShiftARM(opcode, shift_t);
12695
12696      break;
12697
12698    default:
12699      return false;
12700    }
12701
12702    // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12703    // else imm32;
12704    uint32_t operand2;
12705    if (register_form) {
12706      uint32_t Rm = ReadCoreReg(m, &success);
12707      if (!success)
12708        return false;
12709
12710      operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12711      if (!success)
12712        return false;
12713    } else {
12714      operand2 = imm32;
12715    }
12716
12717    uint32_t Rn = ReadCoreReg(n, &success);
12718    if (!success)
12719      return false;
12720
12721    AddWithCarryResult result;
12722
12723    // case opcode of
12724    switch (code) {
12725    case 0: // when '0000'
12726      // result = R[n] AND operand2; // AND
12727      result.result = Rn & operand2;
12728      break;
12729
12730    case 1: // when '0001'
12731      // result = R[n] EOR operand2; // EOR
12732      result.result = Rn ^ operand2;
12733      break;
12734
12735    case 2: // when '0010'
12736      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12737      result = AddWithCarry(Rn, ~(operand2), 1);
12738      break;
12739
12740    case 3: // when '0011'
12741      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12742      result = AddWithCarry(~(Rn), operand2, 1);
12743      break;
12744
12745    case 4: // when '0100'
12746      // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12747      result = AddWithCarry(Rn, operand2, 0);
12748      break;
12749
12750    case 5: // when '0101'
12751      // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12752      result = AddWithCarry(Rn, operand2, APSR_C);
12753      break;
12754
12755    case 6: // when '0110'
12756      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12757      result = AddWithCarry(Rn, ~(operand2), APSR_C);
12758      break;
12759
12760    case 7: // when '0111'
12761      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12762      result = AddWithCarry(~(Rn), operand2, APSR_C);
12763      break;
12764
12765    case 10: // when '1100'
12766      // result = R[n] OR operand2; // ORR
12767      result.result = Rn | operand2;
12768      break;
12769
12770    case 11: // when '1101'
12771      // result = operand2; // MOV
12772      result.result = operand2;
12773      break;
12774
12775    case 12: // when '1110'
12776      // result = R[n] AND NOT(operand2); // BIC
12777      result.result = Rn & ~(operand2);
12778      break;
12779
12780    case 15: // when '1111'
12781      // result = NOT(operand2); // MVN
12782      result.result = ~(operand2);
12783      break;
12784
12785    default:
12786      return false;
12787    }
12788    // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12789
12790    // For now, in emulation mode, we don't have access to the SPSR, so we will
12791    // use the CPSR instead, and hope for the best.
12792    uint32_t spsr =
12793        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12794    if (!success)
12795      return false;
12796
12797    CPSRWriteByInstr(spsr, 15, true);
12798
12799    // BranchWritePC(result);
12800    EmulateInstruction::Context context;
12801    context.type = eContextAdjustPC;
12802    context.SetImmediate(result.result);
12803
12804    BranchWritePC(context, result.result);
12805  }
12806  return true;
12807}
12808
12809EmulateInstructionARM::ARMOpcode *
12810EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12811                                                  uint32_t arm_isa) {
12812  static ARMOpcode g_arm_opcodes[] = {
12813      // Prologue instructions
12814
12815      // push register(s)
12816      {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12817       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12818      {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12819       &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12820
12821      // set r7 to point to a stack offset
12822      {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12823       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12824      {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12825       &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12826      // copy the stack pointer to ip
12827      {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12828       &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12829      {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12830       &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12831      {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12832       &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12833
12834      // adjust the stack pointer
12835      {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12836       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12837      {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12838       &EmulateInstructionARM::EmulateSUBSPReg,
12839       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12840
12841      // push one register
12842      // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12843      {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12844       &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12845
12846      // vector push consecutive extension register(s)
12847      {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12848       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12849      {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12850       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12851
12852      // Epilogue instructions
12853
12854      {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12855       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12856      {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12857       &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12858      {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12859       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12860      {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12861       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12862
12863      // Supervisor Call (previously Software Interrupt)
12864      {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12865       &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12866
12867      // Branch instructions
12868      // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12869      // "bl <label>".
12870      {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12871       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12872      {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12873       &EmulateInstructionARM::EmulateB, "b #imm24"},
12874      {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12875       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12876      {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12877       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12878      // for example, "bx lr"
12879      {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12880       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12881      // bxj
12882      {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12883       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12884
12885      // Data-processing instructions
12886      // adc (immediate)
12887      {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12888       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12889      // adc (register)
12890      {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12891       &EmulateInstructionARM::EmulateADCReg,
12892       "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12893      // add (immediate)
12894      {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12895       &EmulateInstructionARM::EmulateADDImmARM,
12896       "add{s}<c> <Rd>, <Rn>, #const"},
12897      // add (register)
12898      {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12899       &EmulateInstructionARM::EmulateADDReg,
12900       "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12901      // add (register-shifted register)
12902      {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12903       &EmulateInstructionARM::EmulateADDRegShift,
12904       "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12905      // adr
12906      {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12907       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12908      {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12909       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12910      // and (immediate)
12911      {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12912       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12913      // and (register)
12914      {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12915       &EmulateInstructionARM::EmulateANDReg,
12916       "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12917      // bic (immediate)
12918      {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12919       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12920      // bic (register)
12921      {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12922       &EmulateInstructionARM::EmulateBICReg,
12923       "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12924      // eor (immediate)
12925      {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12927      // eor (register)
12928      {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12929       &EmulateInstructionARM::EmulateEORReg,
12930       "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12931      // orr (immediate)
12932      {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12933       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12934      // orr (register)
12935      {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12936       &EmulateInstructionARM::EmulateORRReg,
12937       "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12938      // rsb (immediate)
12939      {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12940       &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12941      // rsb (register)
12942      {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12943       &EmulateInstructionARM::EmulateRSBReg,
12944       "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12945      // rsc (immediate)
12946      {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12947       &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12948      // rsc (register)
12949      {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12950       &EmulateInstructionARM::EmulateRSCReg,
12951       "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12952      // sbc (immediate)
12953      {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12954       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12955      // sbc (register)
12956      {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12957       &EmulateInstructionARM::EmulateSBCReg,
12958       "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12959      // sub (immediate, ARM)
12960      {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12961       &EmulateInstructionARM::EmulateSUBImmARM,
12962       "sub{s}<c> <Rd>, <Rn>, #<const>"},
12963      // sub (sp minus immediate)
12964      {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12965       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12966      // sub (register)
12967      {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968       &EmulateInstructionARM::EmulateSUBReg,
12969       "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12970      // teq (immediate)
12971      {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12972       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12973      // teq (register)
12974      {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12976      // tst (immediate)
12977      {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12978       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12979      // tst (register)
12980      {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12981       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12982
12983      // mov (immediate)
12984      {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12985       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12986      {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12987       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
12988      // mov (register)
12989      {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12990       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12991      // mvn (immediate)
12992      {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12993       &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12994      // mvn (register)
12995      {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996       &EmulateInstructionARM::EmulateMVNReg,
12997       "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12998      // cmn (immediate)
12999      {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13000       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13001      // cmn (register)
13002      {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13004      // cmp (immediate)
13005      {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13006       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13007      // cmp (register)
13008      {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13009       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13010      // asr (immediate)
13011      {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13012       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13013      // asr (register)
13014      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13015       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13016      // lsl (immediate)
13017      {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13018       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13019      // lsl (register)
13020      {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13021       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13022      // lsr (immediate)
13023      {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13024       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13025      // lsr (register)
13026      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13027       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13028      // rrx is a special case encoding of ror (immediate)
13029      {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13030       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13031      // ror (immediate)
13032      {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13033       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13034      // ror (register)
13035      {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13036       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13037      // mul
13038      {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13039       &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13040
13041      // subs pc, lr and related instructions
13042      {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13043       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13044       "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13045      {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13046       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13047       "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13048
13049      // Load instructions
13050      {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13051       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13052      {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053       &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13054      {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13055       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13056      {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13057       &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13058      {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059       &EmulateInstructionARM::EmulateLDRImmediateARM,
13060       "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13061      {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062       &EmulateInstructionARM::EmulateLDRRegister,
13063       "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13064      {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13066      {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13067       &EmulateInstructionARM::EmulateLDRBRegister,
13068       "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13069      {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13070       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13071      {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13072       &EmulateInstructionARM::EmulateLDRHRegister,
13073       "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13074      {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13075       &EmulateInstructionARM::EmulateLDRSBImmediate,
13076       "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13077      {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13078       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13079      {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13080       &EmulateInstructionARM::EmulateLDRSBRegister,
13081       "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13082      {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13083       &EmulateInstructionARM::EmulateLDRSHImmediate,
13084       "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13085      {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13086       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13087      {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13088       &EmulateInstructionARM::EmulateLDRSHRegister,
13089       "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13090      {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13091       &EmulateInstructionARM::EmulateLDRDImmediate,
13092       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13093      {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13094       &EmulateInstructionARM::EmulateLDRDRegister,
13095       "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13096      {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13097       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13098      {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13099       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13100      {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13101       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13102      {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13103       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13104      {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13105       &EmulateInstructionARM::EmulateVLD1Multiple,
13106       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13107      {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13108       &EmulateInstructionARM::EmulateVLD1Single,
13109       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13110      {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13111       &EmulateInstructionARM::EmulateVLD1SingleAll,
13112       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13113
13114      // Store instructions
13115      {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13116       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13117      {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13118       &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13119      {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13120       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13121      {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13122       &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13123      {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13124       &EmulateInstructionARM::EmulateSTRRegister,
13125       "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13126      {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13127       &EmulateInstructionARM::EmulateSTRHRegister,
13128       "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13129      {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13130       &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13131      {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13132       &EmulateInstructionARM::EmulateSTRBImmARM,
13133       "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13134      {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13135       &EmulateInstructionARM::EmulateSTRImmARM,
13136       "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13137      {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13138       &EmulateInstructionARM::EmulateSTRDImm,
13139       "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13140      {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13141       &EmulateInstructionARM::EmulateSTRDReg,
13142       "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13143      {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13144       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13145      {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13146       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13147      {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13148       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13149      {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13150       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13151      {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13152       &EmulateInstructionARM::EmulateVST1Multiple,
13153       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13154      {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13155       &EmulateInstructionARM::EmulateVST1Single,
13156       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13157
13158      // Other instructions
13159      {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13160       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13161      {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13162       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13163      {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13164       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13165      {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13166       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13167      {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13168       &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13169
13170  };
13171  static const size_t k_num_arm_opcodes = std::size(g_arm_opcodes);
13172
13173  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13174    if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13175        (g_arm_opcodes[i].variants & arm_isa) != 0)
13176      return &g_arm_opcodes[i];
13177  }
13178  return nullptr;
13179}
13180
13181EmulateInstructionARM::ARMOpcode *
13182EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13183                                                    uint32_t arm_isa) {
13184
13185  static ARMOpcode g_thumb_opcodes[] = {
13186      // Prologue instructions
13187
13188      // push register(s)
13189      {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13190       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13191      {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13192       &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13193      {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13194       &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13195
13196      // set r7 to point to a stack offset
13197      {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13198       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13199      // copy the stack pointer to r7
13200      {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13201       &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13202      // move from high register to low register (comes after "mov r7, sp" to
13203      // resolve ambiguity)
13204      {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13205       &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13206
13207      // PC-relative load into register (see also EmulateADDSPRm)
13208      {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13209       &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13210
13211      // adjust the stack pointer
13212      {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13213       &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13214      {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13215       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13216      {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13217       &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13218      {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13219       &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13220      {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13221       &EmulateInstructionARM::EmulateSUBSPReg,
13222       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13223
13224      // vector push consecutive extension register(s)
13225      {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13226       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13227      {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13228       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13229
13230      // Epilogue instructions
13231
13232      {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13233       &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13234      {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13235       &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13236      {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13237       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13238      {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13239       &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13240      {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13241       &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13242      {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13243       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13244      {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13245       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13246
13247      // Supervisor Call (previously Software Interrupt)
13248      {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13249       &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13250
13251      // If Then makes up to four following instructions conditional.
13252      // The next 5 opcode _must_ come before the if then instruction
13253      {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13254       &EmulateInstructionARM::EmulateNop, "nop"},
13255      {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13256       &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13257      {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13258       &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13259      {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13260       &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13261      {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13262       &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13263      {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13264       &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13265
13266      // Branch instructions
13267      // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13268      {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13269       &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13270      {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13271       &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13272      {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13273       &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13274      {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13275       &EmulateInstructionARM::EmulateB,
13276       "b<c>.w #imm8 (outside or last in IT)"},
13277      // J1 == J2 == 1
13278      {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13279       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13280      // J1 == J2 == 1
13281      {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13282       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13283      {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13284       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13285      // for example, "bx lr"
13286      {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13287       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13288      // bxj
13289      {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13290       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13291      // compare and branch
13292      {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13293       &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13294      // table branch byte
13295      {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13296       &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13297      // table branch halfword
13298      {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13299       &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13300
13301      // Data-processing instructions
13302      // adc (immediate)
13303      {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13304       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13305      // adc (register)
13306      {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13307       &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13308      {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13309       &EmulateInstructionARM::EmulateADCReg,
13310       "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13311      // add (register)
13312      {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13313       &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13314      // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13315      // ambiguity decoding the two.
13316      {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13317       &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13318      // adr
13319      {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13320       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13321      {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13322       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13323      {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13324       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13325      // and (immediate)
13326      {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13327       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13328      // and (register)
13329      {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13330       &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13331      {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13332       &EmulateInstructionARM::EmulateANDReg,
13333       "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13334      // bic (immediate)
13335      {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13336       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13337      // bic (register)
13338      {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13339       &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13340      {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13341       &EmulateInstructionARM::EmulateBICReg,
13342       "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13343      // eor (immediate)
13344      {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13345       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13346      // eor (register)
13347      {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13348       &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13349      {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13350       &EmulateInstructionARM::EmulateEORReg,
13351       "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13352      // orr (immediate)
13353      {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13354       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13355      // orr (register)
13356      {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13357       &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13358      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13359       &EmulateInstructionARM::EmulateORRReg,
13360       "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13361      // rsb (immediate)
13362      {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13363       &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13364      {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13365       &EmulateInstructionARM::EmulateRSBImm,
13366       "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13367      // rsb (register)
13368      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13369       &EmulateInstructionARM::EmulateRSBReg,
13370       "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13371      // sbc (immediate)
13372      {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13373       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13374      // sbc (register)
13375      {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13376       &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13377      {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13378       &EmulateInstructionARM::EmulateSBCReg,
13379       "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13380      // add (immediate, Thumb)
13381      {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13382       &EmulateInstructionARM::EmulateADDImmThumb,
13383       "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13384      {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13385       &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13386      {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13387       &EmulateInstructionARM::EmulateADDImmThumb,
13388       "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13389      {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13390       &EmulateInstructionARM::EmulateADDImmThumb,
13391       "addw<c> <Rd>,<Rn>,#<imm12>"},
13392      // sub (immediate, Thumb)
13393      {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13394       &EmulateInstructionARM::EmulateSUBImmThumb,
13395       "subs|sub<c> <Rd>, <Rn> #imm3"},
13396      {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13397       &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13398      {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13399       &EmulateInstructionARM::EmulateSUBImmThumb,
13400       "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13401      {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13402       &EmulateInstructionARM::EmulateSUBImmThumb,
13403       "subw<c> <Rd>, <Rn>, #imm12"},
13404      // sub (sp minus immediate)
13405      {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13406       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13407      {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13408       &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13409      // sub (register)
13410      {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13411       &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13412      {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13413       &EmulateInstructionARM::EmulateSUBReg,
13414       "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13415      // teq (immediate)
13416      {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13417       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13418      // teq (register)
13419      {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13420       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13421      // tst (immediate)
13422      {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13423       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13424      // tst (register)
13425      {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13426       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13427      {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13428       &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13429
13430      // move from high register to high register
13431      {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13432       &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13433      // move from low register to low register
13434      {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13435       &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13436      // mov{s}<c>.w <Rd>, <Rm>
13437      {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13438       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13439      // move immediate
13440      {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13441       &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13442      {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13443       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13444      {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13445       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13446      // mvn (immediate)
13447      {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13448       &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13449      // mvn (register)
13450      {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13451       &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13452      {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13453       &EmulateInstructionARM::EmulateMVNReg,
13454       "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13455      // cmn (immediate)
13456      {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13457       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13458      // cmn (register)
13459      {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13460       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13461      {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13462       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13463      // cmp (immediate)
13464      {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13465       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13466      {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13467       &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13468      // cmp (register) (Rn and Rm both from r0-r7)
13469      {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13470       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13471      // cmp (register) (Rn and Rm not both from r0-r7)
13472      {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13473       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13474      {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13475       &EmulateInstructionARM::EmulateCMPReg,
13476       "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13477      // asr (immediate)
13478      {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13479       &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13480      {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13481       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13482      // asr (register)
13483      {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13484       &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13485      {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13486       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13487      // lsl (immediate)
13488      {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13489       &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13490      {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13491       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13492      // lsl (register)
13493      {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13494       &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13495      {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13496       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13497      // lsr (immediate)
13498      {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13499       &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13500      {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13501       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13502      // lsr (register)
13503      {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13504       &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13505      {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13506       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13507      // rrx is a special case encoding of ror (immediate)
13508      {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13509       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13510      // ror (immediate)
13511      {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13512       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13513      // ror (register)
13514      {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13515       &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13516      {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13517       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13518      // mul
13519      {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13520       &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13521      // mul
13522      {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13523       &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13524
13525      // subs pc, lr and related instructions
13526      {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13527       &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13528
13529      // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13530      // LDM.. Instructions in this table;
13531      // otherwise the wrong instructions will be selected.
13532
13533      {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13534       &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13535      {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13536       &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13537
13538      // Load instructions
13539      {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13540       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13541      {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13542       &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13543      {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13544       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13545      {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13546       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13547      {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13548       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13549      {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13550       &EmulateInstructionARM::EmulateLDRRtRnImm,
13551       "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13552      {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13553       &EmulateInstructionARM::EmulateLDRRtRnImm,
13554       "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13555      // Thumb2 PC-relative load into register
13556      {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13557       &EmulateInstructionARM::EmulateLDRRtPCRelative,
13558       "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13559      {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13560       &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13561      {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13562       &EmulateInstructionARM::EmulateLDRRegister,
13563       "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13564      {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13565       &EmulateInstructionARM::EmulateLDRBImmediate,
13566       "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13567      {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13568       &EmulateInstructionARM::EmulateLDRBImmediate,
13569       "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13570      {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13571       &EmulateInstructionARM::EmulateLDRBImmediate,
13572       "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13573      {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13574       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13575      {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13576       &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13577      {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13578       &EmulateInstructionARM::EmulateLDRBRegister,
13579       "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13580      {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13581       &EmulateInstructionARM::EmulateLDRHImmediate,
13582       "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13583      {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13584       &EmulateInstructionARM::EmulateLDRHImmediate,
13585       "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13586      {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13587       &EmulateInstructionARM::EmulateLDRHImmediate,
13588       "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13589      {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13590       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13591      {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13592       &EmulateInstructionARM::EmulateLDRHRegister,
13593       "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13594      {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13595       &EmulateInstructionARM::EmulateLDRHRegister,
13596       "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13597      {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13598       &EmulateInstructionARM::EmulateLDRSBImmediate,
13599       "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13600      {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13601       &EmulateInstructionARM::EmulateLDRSBImmediate,
13602       "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13603      {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13604       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13605      {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13606       &EmulateInstructionARM::EmulateLDRSBRegister,
13607       "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13608      {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13609       &EmulateInstructionARM::EmulateLDRSBRegister,
13610       "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13611      {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13612       &EmulateInstructionARM::EmulateLDRSHImmediate,
13613       "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13614      {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13615       &EmulateInstructionARM::EmulateLDRSHImmediate,
13616       "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13617      {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13618       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13619      {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13620       &EmulateInstructionARM::EmulateLDRSHRegister,
13621       "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13622      {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13623       &EmulateInstructionARM::EmulateLDRSHRegister,
13624       "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13625      {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13626       &EmulateInstructionARM::EmulateLDRDImmediate,
13627       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13628      {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13629       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13630      {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13631       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13632      {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13633       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13634      {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13635       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13636      {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13637       &EmulateInstructionARM::EmulateVLD1Multiple,
13638       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13639      {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13640       &EmulateInstructionARM::EmulateVLD1Single,
13641       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13642      {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13643       &EmulateInstructionARM::EmulateVLD1SingleAll,
13644       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13645
13646      // Store instructions
13647      {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13648       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13649      {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13650       &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13651      {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13652       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13653      {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13654       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13655      {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13656       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13657      {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13658       &EmulateInstructionARM::EmulateSTRThumb,
13659       "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13660      {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13661       &EmulateInstructionARM::EmulateSTRThumb,
13662       "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13663      {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13664       &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13665      {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13666       &EmulateInstructionARM::EmulateSTRRegister,
13667       "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13668      {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13669       &EmulateInstructionARM::EmulateSTRBThumb,
13670       "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13671      {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13672       &EmulateInstructionARM::EmulateSTRBThumb,
13673       "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13674      {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13675       &EmulateInstructionARM::EmulateSTRBThumb,
13676       "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13677      {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13678       &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13679      {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13680       &EmulateInstructionARM::EmulateSTRHRegister,
13681       "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13682      {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13683       &EmulateInstructionARM::EmulateSTREX,
13684       "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13685      {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13686       &EmulateInstructionARM::EmulateSTRDImm,
13687       "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13688      {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13689       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13690      {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13691       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13692      {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13693       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13694      {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13695       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13696      {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13697       &EmulateInstructionARM::EmulateVST1Multiple,
13698       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13699      {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13700       &EmulateInstructionARM::EmulateVST1Single,
13701       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13702
13703      // Other instructions
13704      {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13705       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13706      {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13707       &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13708      {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13709       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13710      {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13711       &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13712      {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13713       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13714      {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13715       &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13716      {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13717       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13718      {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13719       &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13720  };
13721
13722  const size_t k_num_thumb_opcodes = std::size(g_thumb_opcodes);
13723  for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13724    if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13725        (g_thumb_opcodes[i].variants & arm_isa) != 0)
13726      return &g_thumb_opcodes[i];
13727  }
13728  return nullptr;
13729}
13730
13731bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13732  m_arch = arch;
13733  m_arm_isa = 0;
13734  llvm::StringRef arch_cstr = arch.GetArchitectureName();
13735  if (arch_cstr.equals_insensitive("armv4t"))
13736    m_arm_isa = ARMv4T;
13737  else if (arch_cstr.equals_insensitive("armv5tej"))
13738    m_arm_isa = ARMv5TEJ;
13739  else if (arch_cstr.equals_insensitive("armv5te"))
13740    m_arm_isa = ARMv5TE;
13741  else if (arch_cstr.equals_insensitive("armv5t"))
13742    m_arm_isa = ARMv5T;
13743  else if (arch_cstr.equals_insensitive("armv6k"))
13744    m_arm_isa = ARMv6K;
13745  else if (arch_cstr.equals_insensitive("armv6t2"))
13746    m_arm_isa = ARMv6T2;
13747  else if (arch_cstr.equals_insensitive("armv7s"))
13748    m_arm_isa = ARMv7S;
13749  else if (arch_cstr.equals_insensitive("arm"))
13750    m_arm_isa = ARMvAll;
13751  else if (arch_cstr.equals_insensitive("thumb"))
13752    m_arm_isa = ARMvAll;
13753  else if (arch_cstr.starts_with_insensitive("armv4"))
13754    m_arm_isa = ARMv4;
13755  else if (arch_cstr.starts_with_insensitive("armv6"))
13756    m_arm_isa = ARMv6;
13757  else if (arch_cstr.starts_with_insensitive("armv7"))
13758    m_arm_isa = ARMv7;
13759  else if (arch_cstr.starts_with_insensitive("armv8"))
13760    m_arm_isa = ARMv8;
13761  return m_arm_isa != 0;
13762}
13763
13764bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13765                                           const Address &inst_addr,
13766                                           Target *target) {
13767  if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13768    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13769        m_arch.IsAlwaysThumbInstructions())
13770      m_opcode_mode = eModeThumb;
13771    else {
13772      AddressClass addr_class = inst_addr.GetAddressClass();
13773
13774      if ((addr_class == AddressClass::eCode) ||
13775          (addr_class == AddressClass::eUnknown))
13776        m_opcode_mode = eModeARM;
13777      else if (addr_class == AddressClass::eCodeAlternateISA)
13778        m_opcode_mode = eModeThumb;
13779      else
13780        return false;
13781    }
13782    if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13783      m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13784    else
13785      m_opcode_cpsr = CPSR_MODE_USR;
13786    return true;
13787  }
13788  return false;
13789}
13790
13791bool EmulateInstructionARM::ReadInstruction() {
13792  bool success = false;
13793  m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13794                                       LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13795  if (success) {
13796    addr_t pc =
13797        ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13798                             LLDB_INVALID_ADDRESS, &success);
13799    if (success) {
13800      Context read_inst_context;
13801      read_inst_context.type = eContextReadOpcode;
13802      read_inst_context.SetNoArgs();
13803
13804      if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13805        m_opcode_mode = eModeThumb;
13806        uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13807
13808        if (success) {
13809          if ((thumb_opcode & 0xe000) != 0xe000 ||
13810              ((thumb_opcode & 0x1800u) == 0)) {
13811            m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13812          } else {
13813            m_opcode.SetOpcode32(
13814                (thumb_opcode << 16) |
13815                    MemARead(read_inst_context, pc + 2, 2, 0, &success),
13816                GetByteOrder());
13817          }
13818        }
13819      } else {
13820        m_opcode_mode = eModeARM;
13821        m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13822                             GetByteOrder());
13823      }
13824
13825      if (!m_ignore_conditions) {
13826        // If we are not ignoreing the conditions then init the it session from
13827        // the current value of cpsr.
13828        uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13829                      Bits32(m_opcode_cpsr, 26, 25);
13830        if (it != 0)
13831          m_it_session.InitIT(it);
13832      }
13833    }
13834  }
13835  if (!success) {
13836    m_opcode_mode = eModeInvalid;
13837    m_addr = LLDB_INVALID_ADDRESS;
13838  }
13839  return success;
13840}
13841
13842uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13843
13844bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13845  // If we are ignoring conditions, then always return true. this allows us to
13846  // iterate over disassembly code and still emulate an instruction even if we
13847  // don't have all the right bits set in the CPSR register...
13848  if (m_ignore_conditions)
13849    return true;
13850
13851  const uint32_t cond = CurrentCond(opcode);
13852  if (cond == UINT32_MAX)
13853    return false;
13854
13855  bool result = false;
13856  switch (UnsignedBits(cond, 3, 1)) {
13857  case 0:
13858    if (m_opcode_cpsr == 0)
13859      result = true;
13860    else
13861      result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13862    break;
13863  case 1:
13864    if (m_opcode_cpsr == 0)
13865      result = true;
13866    else
13867      result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13868    break;
13869  case 2:
13870    if (m_opcode_cpsr == 0)
13871      result = true;
13872    else
13873      result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13874    break;
13875  case 3:
13876    if (m_opcode_cpsr == 0)
13877      result = true;
13878    else
13879      result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13880    break;
13881  case 4:
13882    if (m_opcode_cpsr == 0)
13883      result = true;
13884    else
13885      result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13886               ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13887    break;
13888  case 5:
13889    if (m_opcode_cpsr == 0)
13890      result = true;
13891    else {
13892      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13893      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13894      result = n == v;
13895    }
13896    break;
13897  case 6:
13898    if (m_opcode_cpsr == 0)
13899      result = true;
13900    else {
13901      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13902      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13903      result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13904    }
13905    break;
13906  case 7:
13907    // Always execute (cond == 0b1110, or the special 0b1111 which gives
13908    // opcodes different meanings, but always means execution happens.
13909    return true;
13910  }
13911
13912  if (cond & 1)
13913    result = !result;
13914  return result;
13915}
13916
13917uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13918  switch (m_opcode_mode) {
13919  case eModeInvalid:
13920    break;
13921
13922  case eModeARM:
13923    return UnsignedBits(opcode, 31, 28);
13924
13925  case eModeThumb:
13926    // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13927    // 'cond' field of the encoding.
13928    {
13929      const uint32_t byte_size = m_opcode.GetByteSize();
13930      if (byte_size == 2) {
13931        if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13932          return Bits32(opcode, 11, 8);
13933      } else if (byte_size == 4) {
13934        if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13935            Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13936          return Bits32(opcode, 25, 22);
13937        }
13938      } else
13939        // We have an invalid thumb instruction, let's bail out.
13940        break;
13941
13942      return m_it_session.GetCond();
13943    }
13944  }
13945  return UINT32_MAX; // Return invalid value
13946}
13947
13948bool EmulateInstructionARM::InITBlock() {
13949  return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13950}
13951
13952bool EmulateInstructionARM::LastInITBlock() {
13953  return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13954}
13955
13956bool EmulateInstructionARM::BadMode(uint32_t mode) {
13957
13958  switch (mode) {
13959  case 16:
13960    return false; // '10000'
13961  case 17:
13962    return false; // '10001'
13963  case 18:
13964    return false; // '10010'
13965  case 19:
13966    return false; // '10011'
13967  case 22:
13968    return false; // '10110'
13969  case 23:
13970    return false; // '10111'
13971  case 27:
13972    return false; // '11011'
13973  case 31:
13974    return false; // '11111'
13975  default:
13976    return true;
13977  }
13978  return true;
13979}
13980
13981bool EmulateInstructionARM::CurrentModeIsPrivileged() {
13982  uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
13983
13984  if (BadMode(mode))
13985    return false;
13986
13987  if (mode == 16)
13988    return false;
13989
13990  return true;
13991}
13992
13993void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
13994                                             bool affect_execstate) {
13995  bool privileged = CurrentModeIsPrivileged();
13996
13997  uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
13998
13999  if (BitIsSet(bytemask, 3)) {
14000    tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14001    if (affect_execstate)
14002      tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14003  }
14004
14005  if (BitIsSet(bytemask, 2)) {
14006    tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14007  }
14008
14009  if (BitIsSet(bytemask, 1)) {
14010    if (affect_execstate)
14011      tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14012    tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14013    if (privileged)
14014      tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14015  }
14016
14017  if (BitIsSet(bytemask, 0)) {
14018    if (privileged)
14019      tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14020    if (affect_execstate)
14021      tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14022    if (privileged)
14023      tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14024  }
14025
14026  m_opcode_cpsr = tmp_cpsr;
14027}
14028
14029bool EmulateInstructionARM::BranchWritePC(const Context &context,
14030                                          uint32_t addr) {
14031  addr_t target;
14032
14033  // Check the current instruction set.
14034  if (CurrentInstrSet() == eModeARM)
14035    target = addr & 0xfffffffc;
14036  else
14037    target = addr & 0xfffffffe;
14038
14039  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14040                               LLDB_REGNUM_GENERIC_PC, target);
14041}
14042
14043// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14044// inspecting addr.
14045bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14046  addr_t target;
14047  // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14048  // we want to record it and issue a WriteRegister callback so the clients can
14049  // track the mode changes accordingly.
14050  bool cpsr_changed = false;
14051
14052  if (BitIsSet(addr, 0)) {
14053    if (CurrentInstrSet() != eModeThumb) {
14054      SelectInstrSet(eModeThumb);
14055      cpsr_changed = true;
14056    }
14057    target = addr & 0xfffffffe;
14058    context.SetISA(eModeThumb);
14059  } else if (BitIsClear(addr, 1)) {
14060    if (CurrentInstrSet() != eModeARM) {
14061      SelectInstrSet(eModeARM);
14062      cpsr_changed = true;
14063    }
14064    target = addr & 0xfffffffc;
14065    context.SetISA(eModeARM);
14066  } else
14067    return false; // address<1:0> == '10' => UNPREDICTABLE
14068
14069  if (cpsr_changed) {
14070    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14071                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14072      return false;
14073  }
14074  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14075                               LLDB_REGNUM_GENERIC_PC, target);
14076}
14077
14078// Dispatches to either BXWritePC or BranchWritePC based on architecture
14079// versions.
14080bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14081  if (ArchVersion() >= ARMv5T)
14082    return BXWritePC(context, addr);
14083  else
14084    return BranchWritePC((const Context)context, addr);
14085}
14086
14087// Dispatches to either BXWritePC or BranchWritePC based on architecture
14088// versions and current instruction set.
14089bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14090  if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14091    return BXWritePC(context, addr);
14092  else
14093    return BranchWritePC((const Context)context, addr);
14094}
14095
14096EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14097  return m_opcode_mode;
14098}
14099
14100// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14101// ReadInstruction() is performed.  This function has a side effect of updating
14102// the m_new_inst_cpsr member variable if necessary.
14103bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14104  m_new_inst_cpsr = m_opcode_cpsr;
14105  switch (arm_or_thumb) {
14106  default:
14107    return false;
14108  case eModeARM:
14109    // Clear the T bit.
14110    m_new_inst_cpsr &= ~MASK_CPSR_T;
14111    break;
14112  case eModeThumb:
14113    // Set the T bit.
14114    m_new_inst_cpsr |= MASK_CPSR_T;
14115    break;
14116  }
14117  return true;
14118}
14119
14120// This function returns TRUE if the processor currently provides support for
14121// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14122// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
14123bool EmulateInstructionARM::UnalignedSupport() {
14124  return (ArchVersion() >= ARMv7);
14125}
14126
14127// The main addition and subtraction instructions can produce status
14128// information about both unsigned carry and signed overflow conditions.  This
14129// status information can be used to synthesize multi-word additions and
14130// subtractions.
14131EmulateInstructionARM::AddWithCarryResult
14132EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14133  uint32_t result;
14134  uint8_t carry_out;
14135  uint8_t overflow;
14136
14137  uint64_t unsigned_sum = x + y + carry_in;
14138  int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14139
14140  result = UnsignedBits(unsigned_sum, 31, 0);
14141  //    carry_out = (result == unsigned_sum ? 0 : 1);
14142  overflow = ((int32_t)result == signed_sum ? 0 : 1);
14143
14144  if (carry_in)
14145    carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14146  else
14147    carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14148
14149  AddWithCarryResult res = {result, carry_out, overflow};
14150  return res;
14151}
14152
14153uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14154  lldb::RegisterKind reg_kind;
14155  uint32_t reg_num;
14156  switch (num) {
14157  case SP_REG:
14158    reg_kind = eRegisterKindGeneric;
14159    reg_num = LLDB_REGNUM_GENERIC_SP;
14160    break;
14161  case LR_REG:
14162    reg_kind = eRegisterKindGeneric;
14163    reg_num = LLDB_REGNUM_GENERIC_RA;
14164    break;
14165  case PC_REG:
14166    reg_kind = eRegisterKindGeneric;
14167    reg_num = LLDB_REGNUM_GENERIC_PC;
14168    break;
14169  default:
14170    if (num < SP_REG) {
14171      reg_kind = eRegisterKindDWARF;
14172      reg_num = dwarf_r0 + num;
14173    } else {
14174      // assert(0 && "Invalid register number");
14175      *success = false;
14176      return UINT32_MAX;
14177    }
14178    break;
14179  }
14180
14181  // Read our register.
14182  uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14183
14184  // When executing an ARM instruction , PC reads as the address of the current
14185  // instruction plus 8. When executing a Thumb instruction , PC reads as the
14186  // address of the current instruction plus 4.
14187  if (num == 15) {
14188    if (CurrentInstrSet() == eModeARM)
14189      val += 8;
14190    else
14191      val += 4;
14192  }
14193
14194  return val;
14195}
14196
14197// Write the result to the ARM core register Rd, and optionally update the
14198// condition flags based on the result.
14199//
14200// This helper method tries to encapsulate the following pseudocode from the
14201// ARM Architecture Reference Manual:
14202//
14203// if d == 15 then         // Can only occur for encoding A1
14204//     ALUWritePC(result); // setflags is always FALSE here
14205// else
14206//     R[d] = result;
14207//     if setflags then
14208//         APSR.N = result<31>;
14209//         APSR.Z = IsZeroBit(result);
14210//         APSR.C = carry;
14211//         // APSR.V unchanged
14212//
14213// In the above case, the API client does not pass in the overflow arg, which
14214// defaults to ~0u.
14215bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14216    Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14217    const uint32_t carry, const uint32_t overflow) {
14218  if (Rd == 15) {
14219    if (!ALUWritePC(context, result))
14220      return false;
14221  } else {
14222    lldb::RegisterKind reg_kind;
14223    uint32_t reg_num;
14224    switch (Rd) {
14225    case SP_REG:
14226      reg_kind = eRegisterKindGeneric;
14227      reg_num = LLDB_REGNUM_GENERIC_SP;
14228      break;
14229    case LR_REG:
14230      reg_kind = eRegisterKindGeneric;
14231      reg_num = LLDB_REGNUM_GENERIC_RA;
14232      break;
14233    default:
14234      reg_kind = eRegisterKindDWARF;
14235      reg_num = dwarf_r0 + Rd;
14236    }
14237    if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14238      return false;
14239    if (setflags)
14240      return WriteFlags(context, result, carry, overflow);
14241  }
14242  return true;
14243}
14244
14245// This helper method tries to encapsulate the following pseudocode from the
14246// ARM Architecture Reference Manual:
14247//
14248// APSR.N = result<31>;
14249// APSR.Z = IsZeroBit(result);
14250// APSR.C = carry;
14251// APSR.V = overflow
14252//
14253// Default arguments can be specified for carry and overflow parameters, which
14254// means not to update the respective flags.
14255bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14256                                       const uint32_t carry,
14257                                       const uint32_t overflow) {
14258  m_new_inst_cpsr = m_opcode_cpsr;
14259  SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14260  SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14261  if (carry != ~0u)
14262    SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14263  if (overflow != ~0u)
14264    SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14265  if (m_new_inst_cpsr != m_opcode_cpsr) {
14266    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14267                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14268      return false;
14269  }
14270  return true;
14271}
14272
14273bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14274  ARMOpcode *opcode_data = nullptr;
14275
14276  if (m_opcode_mode == eModeThumb)
14277    opcode_data =
14278        GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14279  else if (m_opcode_mode == eModeARM)
14280    opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14281
14282  const bool auto_advance_pc =
14283      evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14284  m_ignore_conditions =
14285      evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14286
14287  bool success = false;
14288  if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14289    m_opcode_cpsr =
14290        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14291  }
14292
14293  // Only return false if we are unable to read the CPSR if we care about
14294  // conditions
14295  if (!success && !m_ignore_conditions)
14296    return false;
14297
14298  uint32_t orig_pc_value = 0;
14299  if (auto_advance_pc) {
14300    orig_pc_value =
14301        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14302    if (!success)
14303      return false;
14304  }
14305
14306  // Call the Emulate... function if we managed to decode the opcode.
14307  if (opcode_data) {
14308    success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14309                                             opcode_data->encoding);
14310    if (!success)
14311      return false;
14312  }
14313
14314  // Advance the ITSTATE bits to their values for the next instruction if we
14315  // haven't just executed an IT instruction what initialized it.
14316  if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14317      (opcode_data == nullptr ||
14318       opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14319    m_it_session.ITAdvance();
14320
14321  if (auto_advance_pc) {
14322    uint32_t after_pc_value =
14323        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14324    if (!success)
14325      return false;
14326
14327    if (after_pc_value == orig_pc_value) {
14328      after_pc_value += m_opcode.GetByteSize();
14329
14330      EmulateInstruction::Context context;
14331      context.type = eContextAdvancePC;
14332      context.SetNoArgs();
14333      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14334                                 after_pc_value))
14335        return false;
14336    }
14337  }
14338  return true;
14339}
14340
14341EmulateInstruction::InstructionCondition
14342EmulateInstructionARM::GetInstructionCondition() {
14343  const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14344  if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14345    return EmulateInstruction::UnconditionalCondition;
14346  return cond;
14347}
14348
14349bool EmulateInstructionARM::TestEmulation(Stream &out_stream, ArchSpec &arch,
14350                                          OptionValueDictionary *test_data) {
14351  if (!test_data) {
14352    out_stream.Printf("TestEmulation: Missing test data.\n");
14353    return false;
14354  }
14355
14356  static constexpr llvm::StringLiteral opcode_key("opcode");
14357  static constexpr llvm::StringLiteral before_key("before_state");
14358  static constexpr llvm::StringLiteral after_key("after_state");
14359
14360  OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14361
14362  uint32_t test_opcode;
14363  if ((value_sp.get() == nullptr) ||
14364      (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14365    out_stream.Printf("TestEmulation: Error reading opcode from test file.\n");
14366    return false;
14367  }
14368  test_opcode = value_sp->GetValueAs<uint64_t>().value_or(0);
14369
14370  if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14371      arch.IsAlwaysThumbInstructions()) {
14372    m_opcode_mode = eModeThumb;
14373    if (test_opcode < 0x10000)
14374      m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14375    else
14376      m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14377  } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14378    m_opcode_mode = eModeARM;
14379    m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14380  } else {
14381    out_stream.Printf("TestEmulation:  Invalid arch.\n");
14382    return false;
14383  }
14384
14385  EmulationStateARM before_state;
14386  EmulationStateARM after_state;
14387
14388  value_sp = test_data->GetValueForKey(before_key);
14389  if ((value_sp.get() == nullptr) ||
14390      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14391    out_stream.Printf("TestEmulation:  Failed to find 'before' state.\n");
14392    return false;
14393  }
14394
14395  OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14396  if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14397    out_stream.Printf("TestEmulation:  Failed loading 'before' state.\n");
14398    return false;
14399  }
14400
14401  value_sp = test_data->GetValueForKey(after_key);
14402  if ((value_sp.get() == nullptr) ||
14403      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14404    out_stream.Printf("TestEmulation:  Failed to find 'after' state.\n");
14405    return false;
14406  }
14407
14408  state_dictionary = value_sp->GetAsDictionary();
14409  if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14410    out_stream.Printf("TestEmulation: Failed loading 'after' state.\n");
14411    return false;
14412  }
14413
14414  SetBaton((void *)&before_state);
14415  SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14416               &EmulationStateARM::WritePseudoMemory,
14417               &EmulationStateARM::ReadPseudoRegister,
14418               &EmulationStateARM::WritePseudoRegister);
14419
14420  bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14421  if (!success) {
14422    out_stream.Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14423    return false;
14424  }
14425
14426  success = before_state.CompareState(after_state, out_stream);
14427  if (!success)
14428    out_stream.Printf("TestEmulation:  State after emulation does not match "
14429                      "'after' state.\n");
14430
14431  return success;
14432}
14433//
14434//
14435// const char *
14436// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14437//{
14438//    if (reg_kind == eRegisterKindGeneric)
14439//    {
14440//        switch (reg_num)
14441//        {
14442//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14443//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14444//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14445//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14446//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14447//        default: return NULL;
14448//        }
14449//    }
14450//    else if (reg_kind == eRegisterKindDWARF)
14451//    {
14452//        return GetARMDWARFRegisterName (reg_num);
14453//    }
14454//    return NULL;
14455//}
14456//
14457bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14458  unwind_plan.Clear();
14459  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14460
14461  UnwindPlan::RowSP row(new UnwindPlan::Row);
14462
14463  // Our previous Call Frame Address is the stack pointer
14464  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14465
14466  unwind_plan.AppendRow(row);
14467  unwind_plan.SetSourceName("EmulateInstructionARM");
14468  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14469  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14470  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
14471  unwind_plan.SetReturnAddressRegister(dwarf_lr);
14472  return true;
14473}
14474