xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (revision fc55c20355d889bf3d3f81d94b3614a0c4253fa0)
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 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 LLDB_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 
45 static 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.
605 static 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.
615 bool 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.
634 void 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.
646 bool ITSession::InITBlock() { return ITCounter != 0; }
647 
648 // Return true if we're the last instruction inside an IT Block.
649 bool ITSession::LastInITBlock() { return ITCounter == 1; }
650 
651 // Get condition bits for the current thumb instruction.
652 uint32_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 
708 void EmulateInstructionARM::Initialize() {
709   PluginManager::RegisterPlugin(GetPluginNameStatic(),
710                                 GetPluginDescriptionStatic(), CreateInstance);
711 }
712 
713 void EmulateInstructionARM::Terminate() {
714   PluginManager::UnregisterPlugin(CreateInstance);
715 }
716 
717 llvm::StringRef EmulateInstructionARM::GetPluginDescriptionStatic() {
718   return "Emulate instructions for the ARM architecture.";
719 }
720 
721 EmulateInstruction *
722 EmulateInstructionARM::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 
744 bool 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.
755 bool 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.
768 bool 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 
786 std::optional<RegisterInfo>
787 EmulateInstructionARM::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 
821 uint32_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   // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
834     is_apple = true;
835     break;
836   default:
837     break;
838   }
839 
840   /* On Apple iOS et al, the frame pointer register is always r7.
841    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
842    * Windows on ARM, which is in thumb mode, uses r11 though.
843    */
844 
845   uint32_t fp_regnum = 11;
846 
847   if (is_apple)
848     fp_regnum = 7;
849 
850   if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
851     fp_regnum = 7;
852 
853   return fp_regnum;
854 }
855 
856 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
857   bool is_apple = false;
858   if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
859     is_apple = true;
860   switch (m_arch.GetTriple().getOS()) {
861   case llvm::Triple::Darwin:
862   case llvm::Triple::MacOSX:
863   case llvm::Triple::IOS:
864     is_apple = true;
865     break;
866   default:
867     break;
868   }
869 
870   /* On Apple iOS et al, the frame pointer register is always r7.
871    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
872    * Windows on ARM, which is in thumb mode, uses r11 though.
873    */
874 
875   uint32_t fp_regnum = dwarf_r11;
876 
877   if (is_apple)
878     fp_regnum = dwarf_r7;
879 
880   if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
881     fp_regnum = dwarf_r7;
882 
883   return fp_regnum;
884 }
885 
886 // Push Multiple Registers stores multiple registers to the stack, storing to
887 // consecutive memory locations ending just below the address in SP, and
888 // updates
889 // SP to point to the start of the stored data.
890 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
891                                         const ARMEncoding encoding) {
892 #if 0
893     // ARM pseudo code...
894     if (ConditionPassed())
895     {
896         EncodingSpecificOperations();
897         NullCheckIfThumbEE(13);
898         address = SP - 4*BitCount(registers);
899 
900         for (i = 0 to 14)
901         {
902             if (registers<i> == '1')
903             {
904                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
905                     MemA[address,4] = bits(32) UNKNOWN;
906                 else
907                     MemA[address,4] = R[i];
908                 address = address + 4;
909             }
910         }
911 
912         if (registers<15> == '1') // Only possible for encoding A1 or A2
913             MemA[address,4] = PCStoreValue();
914 
915         SP = SP - 4*BitCount(registers);
916     }
917 #endif
918 
919   bool success = false;
920   if (ConditionPassed(opcode)) {
921     const uint32_t addr_byte_size = GetAddressByteSize();
922     const addr_t sp = ReadCoreReg(SP_REG, &success);
923     if (!success)
924       return false;
925     uint32_t registers = 0;
926     uint32_t Rt; // the source register
927     switch (encoding) {
928     case eEncodingT1:
929       registers = Bits32(opcode, 7, 0);
930       // The M bit represents LR.
931       if (Bit32(opcode, 8))
932         registers |= (1u << 14);
933       // if BitCount(registers) < 1 then UNPREDICTABLE;
934       if (BitCount(registers) < 1)
935         return false;
936       break;
937     case eEncodingT2:
938       // Ignore bits 15 & 13.
939       registers = Bits32(opcode, 15, 0) & ~0xa000;
940       // if BitCount(registers) < 2 then UNPREDICTABLE;
941       if (BitCount(registers) < 2)
942         return false;
943       break;
944     case eEncodingT3:
945       Rt = Bits32(opcode, 15, 12);
946       // if BadReg(t) then UNPREDICTABLE;
947       if (BadReg(Rt))
948         return false;
949       registers = (1u << Rt);
950       break;
951     case eEncodingA1:
952       registers = Bits32(opcode, 15, 0);
953       // Instead of return false, let's handle the following case as well,
954       // which amounts to pushing one reg onto the full descending stacks.
955       // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
956       break;
957     case eEncodingA2:
958       Rt = Bits32(opcode, 15, 12);
959       // if t == 13 then UNPREDICTABLE;
960       if (Rt == dwarf_sp)
961         return false;
962       registers = (1u << Rt);
963       break;
964     default:
965       return false;
966     }
967     addr_t sp_offset = addr_byte_size * BitCount(registers);
968     addr_t addr = sp - sp_offset;
969     uint32_t i;
970 
971     EmulateInstruction::Context context;
972     context.type = EmulateInstruction::eContextPushRegisterOnStack;
973     std::optional<RegisterInfo> sp_reg =
974         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
975     for (i = 0; i < 15; ++i) {
976       if (BitIsSet(registers, i)) {
977         std::optional<RegisterInfo> reg_info =
978             GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
979         context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
980         uint32_t reg_value = ReadCoreReg(i, &success);
981         if (!success)
982           return false;
983         if (!MemAWrite(context, addr, reg_value, addr_byte_size))
984           return false;
985         addr += addr_byte_size;
986       }
987     }
988 
989     if (BitIsSet(registers, 15)) {
990       std::optional<RegisterInfo> reg_info =
991           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
992       context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
993       const uint32_t pc = ReadCoreReg(PC_REG, &success);
994       if (!success)
995         return false;
996       if (!MemAWrite(context, addr, pc, addr_byte_size))
997         return false;
998     }
999 
1000     context.type = EmulateInstruction::eContextAdjustStackPointer;
1001     context.SetImmediateSigned(-sp_offset);
1002 
1003     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1004                                LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1005       return false;
1006   }
1007   return true;
1008 }
1009 
1010 // Pop Multiple Registers loads multiple registers from the stack, loading from
1011 // consecutive memory locations staring at the address in SP, and updates
1012 // SP to point just above the loaded data.
1013 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1014                                        const ARMEncoding encoding) {
1015 #if 0
1016     // ARM pseudo code...
1017     if (ConditionPassed())
1018     {
1019         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1020         address = SP;
1021         for i = 0 to 14
1022             if registers<i> == '1' then
1023                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1024         if registers<15> == '1' then
1025             if UnalignedAllowed then
1026                 LoadWritePC(MemU[address,4]);
1027             else
1028                 LoadWritePC(MemA[address,4]);
1029         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1030         if registers<13> == '1' then SP = bits(32) UNKNOWN;
1031     }
1032 #endif
1033 
1034   bool success = false;
1035 
1036   if (ConditionPassed(opcode)) {
1037     const uint32_t addr_byte_size = GetAddressByteSize();
1038     const addr_t sp = ReadCoreReg(SP_REG, &success);
1039     if (!success)
1040       return false;
1041     uint32_t registers = 0;
1042     uint32_t Rt; // the destination register
1043     switch (encoding) {
1044     case eEncodingT1:
1045       registers = Bits32(opcode, 7, 0);
1046       // The P bit represents PC.
1047       if (Bit32(opcode, 8))
1048         registers |= (1u << 15);
1049       // if BitCount(registers) < 1 then UNPREDICTABLE;
1050       if (BitCount(registers) < 1)
1051         return false;
1052       break;
1053     case eEncodingT2:
1054       // Ignore bit 13.
1055       registers = Bits32(opcode, 15, 0) & ~0x2000;
1056       // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1057       // UNPREDICTABLE;
1058       if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1059         return false;
1060       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1061       // UNPREDICTABLE;
1062       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1063         return false;
1064       break;
1065     case eEncodingT3:
1066       Rt = Bits32(opcode, 15, 12);
1067       // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1068       // UNPREDICTABLE;
1069       if (Rt == 13)
1070         return false;
1071       if (Rt == 15 && InITBlock() && !LastInITBlock())
1072         return false;
1073       registers = (1u << Rt);
1074       break;
1075     case eEncodingA1:
1076       registers = Bits32(opcode, 15, 0);
1077       // Instead of return false, let's handle the following case as well,
1078       // which amounts to popping one reg from the full descending stacks.
1079       // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1080 
1081       // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1082       if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1083         return false;
1084       break;
1085     case eEncodingA2:
1086       Rt = Bits32(opcode, 15, 12);
1087       // if t == 13 then UNPREDICTABLE;
1088       if (Rt == dwarf_sp)
1089         return false;
1090       registers = (1u << Rt);
1091       break;
1092     default:
1093       return false;
1094     }
1095     addr_t sp_offset = addr_byte_size * BitCount(registers);
1096     addr_t addr = sp;
1097     uint32_t i, data;
1098 
1099     EmulateInstruction::Context context;
1100     context.type = EmulateInstruction::eContextPopRegisterOffStack;
1101 
1102     std::optional<RegisterInfo> sp_reg =
1103         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1104 
1105     for (i = 0; i < 15; ++i) {
1106       if (BitIsSet(registers, i)) {
1107         context.SetAddress(addr);
1108         data = MemARead(context, addr, 4, 0, &success);
1109         if (!success)
1110           return false;
1111         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1112                                    data))
1113           return false;
1114         addr += addr_byte_size;
1115       }
1116     }
1117 
1118     if (BitIsSet(registers, 15)) {
1119       context.SetRegisterPlusOffset(*sp_reg, addr - sp);
1120       data = MemARead(context, addr, 4, 0, &success);
1121       if (!success)
1122         return false;
1123       // In ARMv5T and above, this is an interworking branch.
1124       if (!LoadWritePC(context, data))
1125         return false;
1126       // addr += addr_byte_size;
1127     }
1128 
1129     context.type = EmulateInstruction::eContextAdjustStackPointer;
1130     context.SetImmediateSigned(sp_offset);
1131 
1132     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1133                                LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1134       return false;
1135   }
1136   return true;
1137 }
1138 
1139 // Set r7 or ip to point to saved value residing within the stack.
1140 // ADD (SP plus immediate)
1141 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1142                                               const ARMEncoding encoding) {
1143 #if 0
1144     // ARM pseudo code...
1145     if (ConditionPassed())
1146     {
1147         EncodingSpecificOperations();
1148         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1149         if d == 15 then
1150            ALUWritePC(result); // setflags is always FALSE here
1151         else
1152             R[d] = result;
1153             if setflags then
1154                 APSR.N = result<31>;
1155                 APSR.Z = IsZeroBit(result);
1156                 APSR.C = carry;
1157                 APSR.V = overflow;
1158     }
1159 #endif
1160 
1161   bool success = false;
1162 
1163   if (ConditionPassed(opcode)) {
1164     const addr_t sp = ReadCoreReg(SP_REG, &success);
1165     if (!success)
1166       return false;
1167     uint32_t Rd; // the destination register
1168     uint32_t imm32;
1169     switch (encoding) {
1170     case eEncodingT1:
1171       Rd = 7;
1172       imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1173       break;
1174     case eEncodingA1:
1175       Rd = Bits32(opcode, 15, 12);
1176       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1177       break;
1178     default:
1179       return false;
1180     }
1181     addr_t sp_offset = imm32;
1182     addr_t addr = sp + sp_offset; // a pointer to the stack area
1183 
1184     EmulateInstruction::Context context;
1185     if (Rd == GetFramePointerRegisterNumber())
1186       context.type = eContextSetFramePointer;
1187     else
1188       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1189     std::optional<RegisterInfo> sp_reg =
1190         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1191     context.SetRegisterPlusOffset(*sp_reg, sp_offset);
1192 
1193     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1194                                addr))
1195       return false;
1196   }
1197   return true;
1198 }
1199 
1200 // Set r7 or ip to the current stack pointer.
1201 // MOV (register)
1202 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1203                                            const ARMEncoding encoding) {
1204 #if 0
1205     // ARM pseudo code...
1206     if (ConditionPassed())
1207     {
1208         EncodingSpecificOperations();
1209         result = R[m];
1210         if d == 15 then
1211             ALUWritePC(result); // setflags is always FALSE here
1212         else
1213             R[d] = result;
1214             if setflags then
1215                 APSR.N = result<31>;
1216                 APSR.Z = IsZeroBit(result);
1217                 // APSR.C unchanged
1218                 // APSR.V unchanged
1219     }
1220 #endif
1221 
1222   bool success = false;
1223 
1224   if (ConditionPassed(opcode)) {
1225     const addr_t sp = ReadCoreReg(SP_REG, &success);
1226     if (!success)
1227       return false;
1228     uint32_t Rd; // the destination register
1229     switch (encoding) {
1230     case eEncodingT1:
1231       Rd = 7;
1232       break;
1233     case eEncodingA1:
1234       Rd = 12;
1235       break;
1236     default:
1237       return false;
1238     }
1239 
1240     EmulateInstruction::Context context;
1241     if (Rd == GetFramePointerRegisterNumber())
1242       context.type = EmulateInstruction::eContextSetFramePointer;
1243     else
1244       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1245     std::optional<RegisterInfo> sp_reg =
1246         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1247     context.SetRegisterPlusOffset(*sp_reg, 0);
1248 
1249     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1250       return false;
1251   }
1252   return true;
1253 }
1254 
1255 // Move from high register (r8-r15) to low register (r0-r7).
1256 // MOV (register)
1257 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1258                                               const ARMEncoding encoding) {
1259   return EmulateMOVRdRm(opcode, encoding);
1260 }
1261 
1262 // Move from register to register.
1263 // MOV (register)
1264 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1265                                            const ARMEncoding encoding) {
1266 #if 0
1267     // ARM pseudo code...
1268     if (ConditionPassed())
1269     {
1270         EncodingSpecificOperations();
1271         result = R[m];
1272         if d == 15 then
1273             ALUWritePC(result); // setflags is always FALSE here
1274         else
1275             R[d] = result;
1276             if setflags then
1277                 APSR.N = result<31>;
1278                 APSR.Z = IsZeroBit(result);
1279                 // APSR.C unchanged
1280                 // APSR.V unchanged
1281     }
1282 #endif
1283 
1284   bool success = false;
1285 
1286   if (ConditionPassed(opcode)) {
1287     uint32_t Rm; // the source register
1288     uint32_t Rd; // the destination register
1289     bool setflags;
1290     switch (encoding) {
1291     case eEncodingT1:
1292       Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1293       Rm = Bits32(opcode, 6, 3);
1294       setflags = false;
1295       if (Rd == 15 && InITBlock() && !LastInITBlock())
1296         return false;
1297       break;
1298     case eEncodingT2:
1299       Rd = Bits32(opcode, 2, 0);
1300       Rm = Bits32(opcode, 5, 3);
1301       setflags = true;
1302       if (InITBlock())
1303         return false;
1304       break;
1305     case eEncodingT3:
1306       Rd = Bits32(opcode, 11, 8);
1307       Rm = Bits32(opcode, 3, 0);
1308       setflags = BitIsSet(opcode, 20);
1309       // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1310       if (setflags && (BadReg(Rd) || BadReg(Rm)))
1311         return false;
1312       // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1313       // UNPREDICTABLE;
1314       if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1315         return false;
1316       break;
1317     case eEncodingA1:
1318       Rd = Bits32(opcode, 15, 12);
1319       Rm = Bits32(opcode, 3, 0);
1320       setflags = BitIsSet(opcode, 20);
1321 
1322       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1323       // instructions;
1324       if (Rd == 15 && setflags)
1325         return EmulateSUBSPcLrEtc(opcode, encoding);
1326       break;
1327     default:
1328       return false;
1329     }
1330     uint32_t result = ReadCoreReg(Rm, &success);
1331     if (!success)
1332       return false;
1333 
1334     // The context specifies that Rm is to be moved into Rd.
1335     EmulateInstruction::Context context;
1336     if (Rd == 13)
1337       context.type = EmulateInstruction::eContextAdjustStackPointer;
1338     else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1339       context.type = EmulateInstruction::eContextSetFramePointer;
1340     else
1341       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1342     std::optional<RegisterInfo> dwarf_reg =
1343         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
1344     context.SetRegisterPlusOffset(*dwarf_reg, 0);
1345 
1346     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1347       return false;
1348   }
1349   return true;
1350 }
1351 
1352 // Move (immediate) writes an immediate value to the destination register.  It
1353 // can optionally update the condition flags based on the value.
1354 // MOV (immediate)
1355 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1356                                             const ARMEncoding encoding) {
1357 #if 0
1358     // ARM pseudo code...
1359     if (ConditionPassed())
1360     {
1361         EncodingSpecificOperations();
1362         result = imm32;
1363         if d == 15 then         // Can only occur for ARM encoding
1364             ALUWritePC(result); // setflags is always FALSE here
1365         else
1366             R[d] = result;
1367             if setflags then
1368                 APSR.N = result<31>;
1369                 APSR.Z = IsZeroBit(result);
1370                 APSR.C = carry;
1371                 // APSR.V unchanged
1372     }
1373 #endif
1374 
1375   if (ConditionPassed(opcode)) {
1376     uint32_t Rd;    // the destination register
1377     uint32_t imm32; // the immediate value to be written to Rd
1378     uint32_t carry =
1379         0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1380            // for setflags == false, this value is a don't care initialized to
1381            // 0 to silence the static analyzer
1382     bool setflags;
1383     switch (encoding) {
1384     case eEncodingT1:
1385       Rd = Bits32(opcode, 10, 8);
1386       setflags = !InITBlock();
1387       imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1388       carry = APSR_C;
1389 
1390       break;
1391 
1392     case eEncodingT2:
1393       Rd = Bits32(opcode, 11, 8);
1394       setflags = BitIsSet(opcode, 20);
1395       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1396       if (BadReg(Rd))
1397         return false;
1398 
1399       break;
1400 
1401     case eEncodingT3: {
1402       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1403       // 32);
1404       Rd = Bits32(opcode, 11, 8);
1405       setflags = false;
1406       uint32_t imm4 = Bits32(opcode, 19, 16);
1407       uint32_t imm3 = Bits32(opcode, 14, 12);
1408       uint32_t i = Bit32(opcode, 26);
1409       uint32_t imm8 = Bits32(opcode, 7, 0);
1410       imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1411 
1412       // if BadReg(d) then UNPREDICTABLE;
1413       if (BadReg(Rd))
1414         return false;
1415     } break;
1416 
1417     case eEncodingA1:
1418       // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1419       // ARMExpandImm_C(imm12, APSR.C);
1420       Rd = Bits32(opcode, 15, 12);
1421       setflags = BitIsSet(opcode, 20);
1422       imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1423 
1424       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1425       // instructions;
1426       if ((Rd == 15) && setflags)
1427         return EmulateSUBSPcLrEtc(opcode, encoding);
1428 
1429       break;
1430 
1431     case eEncodingA2: {
1432       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1433       Rd = Bits32(opcode, 15, 12);
1434       setflags = false;
1435       uint32_t imm4 = Bits32(opcode, 19, 16);
1436       uint32_t imm12 = Bits32(opcode, 11, 0);
1437       imm32 = (imm4 << 12) | imm12;
1438 
1439       // if d == 15 then UNPREDICTABLE;
1440       if (Rd == 15)
1441         return false;
1442     } break;
1443 
1444     default:
1445       return false;
1446     }
1447     uint32_t result = imm32;
1448 
1449     // The context specifies that an immediate is to be moved into Rd.
1450     EmulateInstruction::Context context;
1451     context.type = EmulateInstruction::eContextImmediate;
1452     context.SetNoArgs();
1453 
1454     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1455       return false;
1456   }
1457   return true;
1458 }
1459 
1460 // MUL multiplies two register values.  The least significant 32 bits of the
1461 // result are written to the destination
1462 // register.  These 32 bits do not depend on whether the source register values
1463 // are considered to be signed values or unsigned values.
1464 //
1465 // Optionally, it can update the condition flags based on the result.  In the
1466 // Thumb instruction set, this option is limited to only a few forms of the
1467 // instruction.
1468 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1469                                        const ARMEncoding encoding) {
1470 #if 0
1471     if ConditionPassed() then
1472         EncodingSpecificOperations();
1473         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1474         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1475         result = operand1 * operand2;
1476         R[d] = result<31:0>;
1477         if setflags then
1478             APSR.N = result<31>;
1479             APSR.Z = IsZeroBit(result);
1480             if ArchVersion() == 4 then
1481                 APSR.C = bit UNKNOWN;
1482             // else APSR.C unchanged
1483             // APSR.V always unchanged
1484 #endif
1485 
1486   if (ConditionPassed(opcode)) {
1487     uint32_t d;
1488     uint32_t n;
1489     uint32_t m;
1490     bool setflags;
1491 
1492     // EncodingSpecificOperations();
1493     switch (encoding) {
1494     case eEncodingT1:
1495       // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1496       d = Bits32(opcode, 2, 0);
1497       n = Bits32(opcode, 5, 3);
1498       m = Bits32(opcode, 2, 0);
1499       setflags = !InITBlock();
1500 
1501       // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1502       if ((ArchVersion() < ARMv6) && (d == n))
1503         return false;
1504 
1505       break;
1506 
1507     case eEncodingT2:
1508       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1509       d = Bits32(opcode, 11, 8);
1510       n = Bits32(opcode, 19, 16);
1511       m = Bits32(opcode, 3, 0);
1512       setflags = false;
1513 
1514       // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1515       if (BadReg(d) || BadReg(n) || BadReg(m))
1516         return false;
1517 
1518       break;
1519 
1520     case eEncodingA1:
1521       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1522       d = Bits32(opcode, 19, 16);
1523       n = Bits32(opcode, 3, 0);
1524       m = Bits32(opcode, 11, 8);
1525       setflags = BitIsSet(opcode, 20);
1526 
1527       // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1528       if ((d == 15) || (n == 15) || (m == 15))
1529         return false;
1530 
1531       // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1532       if ((ArchVersion() < ARMv6) && (d == n))
1533         return false;
1534 
1535       break;
1536 
1537     default:
1538       return false;
1539     }
1540 
1541     bool success = false;
1542 
1543     // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1544     // results
1545     uint64_t operand1 =
1546         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1547     if (!success)
1548       return false;
1549 
1550     // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1551     // results
1552     uint64_t operand2 =
1553         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1554     if (!success)
1555       return false;
1556 
1557     // result = operand1 * operand2;
1558     uint64_t result = operand1 * operand2;
1559 
1560     // R[d] = result<31:0>;
1561     std::optional<RegisterInfo> op1_reg =
1562         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
1563     std::optional<RegisterInfo> op2_reg =
1564         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
1565 
1566     EmulateInstruction::Context context;
1567     context.type = eContextArithmetic;
1568     context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
1569 
1570     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1571                                (0x0000ffff & result)))
1572       return false;
1573 
1574     // if setflags then
1575     if (setflags) {
1576       // APSR.N = result<31>;
1577       // APSR.Z = IsZeroBit(result);
1578       m_new_inst_cpsr = m_opcode_cpsr;
1579       SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1580       SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1581       if (m_new_inst_cpsr != m_opcode_cpsr) {
1582         if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1583                                    LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1584           return false;
1585       }
1586 
1587       // if ArchVersion() == 4 then
1588       // APSR.C = bit UNKNOWN;
1589     }
1590   }
1591   return true;
1592 }
1593 
1594 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1595 // the destination register. It can optionally update the condition flags based
1596 // on the value.
1597 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1598                                           const ARMEncoding encoding) {
1599 #if 0
1600     // ARM pseudo code...
1601     if (ConditionPassed())
1602     {
1603         EncodingSpecificOperations();
1604         result = NOT(imm32);
1605         if d == 15 then         // Can only occur for ARM encoding
1606             ALUWritePC(result); // setflags is always FALSE here
1607         else
1608             R[d] = result;
1609             if setflags then
1610                 APSR.N = result<31>;
1611                 APSR.Z = IsZeroBit(result);
1612                 APSR.C = carry;
1613                 // APSR.V unchanged
1614     }
1615 #endif
1616 
1617   if (ConditionPassed(opcode)) {
1618     uint32_t Rd;    // the destination register
1619     uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1620     uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1621     bool setflags;
1622     switch (encoding) {
1623     case eEncodingT1:
1624       Rd = Bits32(opcode, 11, 8);
1625       setflags = BitIsSet(opcode, 20);
1626       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1627       break;
1628     case eEncodingA1:
1629       Rd = Bits32(opcode, 15, 12);
1630       setflags = BitIsSet(opcode, 20);
1631       imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1632 
1633       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1634       // instructions;
1635       if (Rd == 15 && setflags)
1636         return EmulateSUBSPcLrEtc(opcode, encoding);
1637       break;
1638     default:
1639       return false;
1640     }
1641     uint32_t result = ~imm32;
1642 
1643     // The context specifies that an immediate is to be moved into Rd.
1644     EmulateInstruction::Context context;
1645     context.type = EmulateInstruction::eContextImmediate;
1646     context.SetNoArgs();
1647 
1648     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1649       return false;
1650   }
1651   return true;
1652 }
1653 
1654 // Bitwise NOT (register) writes the bitwise inverse of a register value to the
1655 // destination register. It can optionally update the condition flags based on
1656 // the result.
1657 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1658                                           const ARMEncoding encoding) {
1659 #if 0
1660     // ARM pseudo code...
1661     if (ConditionPassed())
1662     {
1663         EncodingSpecificOperations();
1664         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1665         result = NOT(shifted);
1666         if d == 15 then         // Can only occur for ARM encoding
1667             ALUWritePC(result); // setflags is always FALSE here
1668         else
1669             R[d] = result;
1670             if setflags then
1671                 APSR.N = result<31>;
1672                 APSR.Z = IsZeroBit(result);
1673                 APSR.C = carry;
1674                 // APSR.V unchanged
1675     }
1676 #endif
1677 
1678   if (ConditionPassed(opcode)) {
1679     uint32_t Rm; // the source register
1680     uint32_t Rd; // the destination register
1681     ARM_ShifterType shift_t;
1682     uint32_t shift_n; // the shift applied to the value read from Rm
1683     bool setflags;
1684     uint32_t carry; // the carry bit after the shift operation
1685     switch (encoding) {
1686     case eEncodingT1:
1687       Rd = Bits32(opcode, 2, 0);
1688       Rm = Bits32(opcode, 5, 3);
1689       setflags = !InITBlock();
1690       shift_t = SRType_LSL;
1691       shift_n = 0;
1692       if (InITBlock())
1693         return false;
1694       break;
1695     case eEncodingT2:
1696       Rd = Bits32(opcode, 11, 8);
1697       Rm = Bits32(opcode, 3, 0);
1698       setflags = BitIsSet(opcode, 20);
1699       shift_n = DecodeImmShiftThumb(opcode, shift_t);
1700       // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1701       if (BadReg(Rd) || BadReg(Rm))
1702         return false;
1703       break;
1704     case eEncodingA1:
1705       Rd = Bits32(opcode, 15, 12);
1706       Rm = Bits32(opcode, 3, 0);
1707       setflags = BitIsSet(opcode, 20);
1708       shift_n = DecodeImmShiftARM(opcode, shift_t);
1709       break;
1710     default:
1711       return false;
1712     }
1713     bool success = false;
1714     uint32_t value = ReadCoreReg(Rm, &success);
1715     if (!success)
1716       return false;
1717 
1718     uint32_t shifted =
1719         Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1720     if (!success)
1721       return false;
1722     uint32_t result = ~shifted;
1723 
1724     // The context specifies that an immediate is to be moved into Rd.
1725     EmulateInstruction::Context context;
1726     context.type = EmulateInstruction::eContextImmediate;
1727     context.SetNoArgs();
1728 
1729     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1730       return false;
1731   }
1732   return true;
1733 }
1734 
1735 // PC relative immediate load into register, possibly followed by ADD (SP plus
1736 // register).
1737 // LDR (literal)
1738 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1739                                                    const ARMEncoding encoding) {
1740 #if 0
1741     // ARM pseudo code...
1742     if (ConditionPassed())
1743     {
1744         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1745         base = Align(PC,4);
1746         address = if add then (base + imm32) else (base - imm32);
1747         data = MemU[address,4];
1748         if t == 15 then
1749             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1750         elsif UnalignedSupport() || address<1:0> = '00' then
1751             R[t] = data;
1752         else // Can only apply before ARMv7
1753             if CurrentInstrSet() == InstrSet_ARM then
1754                 R[t] = ROR(data, 8*UInt(address<1:0>));
1755             else
1756                 R[t] = bits(32) UNKNOWN;
1757     }
1758 #endif
1759 
1760   if (ConditionPassed(opcode)) {
1761     bool success = false;
1762     const uint32_t pc = ReadCoreReg(PC_REG, &success);
1763     if (!success)
1764       return false;
1765 
1766     // PC relative immediate load context
1767     EmulateInstruction::Context context;
1768     context.type = EmulateInstruction::eContextRegisterPlusOffset;
1769     std::optional<RegisterInfo> pc_reg =
1770         GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
1771     context.SetRegisterPlusOffset(*pc_reg, 0);
1772 
1773     uint32_t Rt;    // the destination register
1774     uint32_t imm32; // immediate offset from the PC
1775     bool add;       // +imm32 or -imm32?
1776     addr_t base;    // the base address
1777     addr_t address; // the PC relative address
1778     uint32_t data;  // the literal data value from the PC relative load
1779     switch (encoding) {
1780     case eEncodingT1:
1781       Rt = Bits32(opcode, 10, 8);
1782       imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1783       add = true;
1784       break;
1785     case eEncodingT2:
1786       Rt = Bits32(opcode, 15, 12);
1787       imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1788       add = BitIsSet(opcode, 23);
1789       if (Rt == 15 && InITBlock() && !LastInITBlock())
1790         return false;
1791       break;
1792     default:
1793       return false;
1794     }
1795 
1796     base = Align(pc, 4);
1797     if (add)
1798       address = base + imm32;
1799     else
1800       address = base - imm32;
1801 
1802     context.SetRegisterPlusOffset(*pc_reg, address - base);
1803     data = MemURead(context, address, 4, 0, &success);
1804     if (!success)
1805       return false;
1806 
1807     if (Rt == 15) {
1808       if (Bits32(address, 1, 0) == 0) {
1809         // In ARMv5T and above, this is an interworking branch.
1810         if (!LoadWritePC(context, data))
1811           return false;
1812       } else
1813         return false;
1814     } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1815       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1816                                  data))
1817         return false;
1818     } else // We don't handle ARM for now.
1819       return false;
1820   }
1821   return true;
1822 }
1823 
1824 // An add operation to adjust the SP.
1825 // ADD (SP plus immediate)
1826 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1827                                             const ARMEncoding encoding) {
1828 #if 0
1829     // ARM pseudo code...
1830     if (ConditionPassed())
1831     {
1832         EncodingSpecificOperations();
1833         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1834         if d == 15 then // Can only occur for ARM encoding
1835             ALUWritePC(result); // setflags is always FALSE here
1836         else
1837             R[d] = result;
1838             if setflags then
1839                 APSR.N = result<31>;
1840                 APSR.Z = IsZeroBit(result);
1841                 APSR.C = carry;
1842                 APSR.V = overflow;
1843     }
1844 #endif
1845 
1846   bool success = false;
1847 
1848   if (ConditionPassed(opcode)) {
1849     const addr_t sp = ReadCoreReg(SP_REG, &success);
1850     if (!success)
1851       return false;
1852     uint32_t imm32; // the immediate operand
1853     uint32_t d;
1854     bool setflags;
1855     switch (encoding) {
1856     case eEncodingT1:
1857       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1858       d = Bits32(opcode, 10, 8);
1859       imm32 = (Bits32(opcode, 7, 0) << 2);
1860       setflags = false;
1861       break;
1862 
1863     case eEncodingT2:
1864       // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1865       d = 13;
1866       imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1867       setflags = false;
1868       break;
1869 
1870     case eEncodingT3:
1871       // d = UInt(Rd); setflags = (S == "1"); imm32 =
1872       // ThumbExpandImm(i:imm3:imm8);
1873       d = Bits32(opcode, 11, 8);
1874       imm32 = ThumbExpandImm(opcode);
1875       setflags = Bit32(opcode, 20);
1876 
1877       // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1878       if (d == 15 && setflags == 1)
1879         return false; // CMN (immediate) not yet supported
1880 
1881       // if d == 15 && S == "0" then UNPREDICTABLE;
1882       if (d == 15 && setflags == 0)
1883         return false;
1884       break;
1885 
1886     case eEncodingT4: {
1887       // if Rn == '1111' then SEE ADR;
1888       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1889       d = Bits32(opcode, 11, 8);
1890       setflags = false;
1891       uint32_t i = Bit32(opcode, 26);
1892       uint32_t imm3 = Bits32(opcode, 14, 12);
1893       uint32_t imm8 = Bits32(opcode, 7, 0);
1894       imm32 = (i << 11) | (imm3 << 8) | imm8;
1895 
1896       // if d == 15 then UNPREDICTABLE;
1897       if (d == 15)
1898         return false;
1899     } break;
1900 
1901     default:
1902       return false;
1903     }
1904     // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1905     AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1906 
1907     EmulateInstruction::Context context;
1908     if (d == 13)
1909       context.type = EmulateInstruction::eContextAdjustStackPointer;
1910     else
1911       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1912 
1913     std::optional<RegisterInfo> sp_reg =
1914         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1915     context.SetRegisterPlusOffset(*sp_reg, res.result - sp);
1916 
1917     if (d == 15) {
1918       if (!ALUWritePC(context, res.result))
1919         return false;
1920     } else {
1921       // R[d] = result;
1922       // if setflags then
1923       //     APSR.N = result<31>;
1924       //     APSR.Z = IsZeroBit(result);
1925       //     APSR.C = carry;
1926       //     APSR.V = overflow;
1927       if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1928                                      res.carry_out, res.overflow))
1929         return false;
1930     }
1931   }
1932   return true;
1933 }
1934 
1935 // An add operation to adjust the SP.
1936 // ADD (SP plus register)
1937 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1938                                            const ARMEncoding encoding) {
1939 #if 0
1940     // ARM pseudo code...
1941     if (ConditionPassed())
1942     {
1943         EncodingSpecificOperations();
1944         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1945         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1946         if d == 15 then
1947             ALUWritePC(result); // setflags is always FALSE here
1948         else
1949             R[d] = result;
1950             if setflags then
1951                 APSR.N = result<31>;
1952                 APSR.Z = IsZeroBit(result);
1953                 APSR.C = carry;
1954                 APSR.V = overflow;
1955     }
1956 #endif
1957 
1958   bool success = false;
1959 
1960   if (ConditionPassed(opcode)) {
1961     const addr_t sp = ReadCoreReg(SP_REG, &success);
1962     if (!success)
1963       return false;
1964     uint32_t Rm; // the second operand
1965     switch (encoding) {
1966     case eEncodingT2:
1967       Rm = Bits32(opcode, 6, 3);
1968       break;
1969     default:
1970       return false;
1971     }
1972     int32_t reg_value = ReadCoreReg(Rm, &success);
1973     if (!success)
1974       return false;
1975 
1976     addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1977 
1978     EmulateInstruction::Context context;
1979     context.type = eContextArithmetic;
1980     std::optional<RegisterInfo> sp_reg =
1981         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1982     std::optional<RegisterInfo> other_reg =
1983         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
1984     context.SetRegisterRegisterOperands(*sp_reg, *other_reg);
1985 
1986     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1987                                LLDB_REGNUM_GENERIC_SP, addr))
1988       return false;
1989   }
1990   return true;
1991 }
1992 
1993 // Branch with Link and Exchange Instruction Sets (immediate) calls a
1994 // subroutine at a PC-relative address, and changes instruction set from ARM to
1995 // Thumb, or from Thumb to ARM.
1996 // BLX (immediate)
1997 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
1998                                                 const ARMEncoding encoding) {
1999 #if 0
2000     // ARM pseudo code...
2001     if (ConditionPassed())
2002     {
2003         EncodingSpecificOperations();
2004         if CurrentInstrSet() == InstrSet_ARM then
2005             LR = PC - 4;
2006         else
2007             LR = PC<31:1> : '1';
2008         if targetInstrSet == InstrSet_ARM then
2009             targetAddress = Align(PC,4) + imm32;
2010         else
2011             targetAddress = PC + imm32;
2012         SelectInstrSet(targetInstrSet);
2013         BranchWritePC(targetAddress);
2014     }
2015 #endif
2016 
2017   bool success = true;
2018 
2019   if (ConditionPassed(opcode)) {
2020     EmulateInstruction::Context context;
2021     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2022     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2023     if (!success)
2024       return false;
2025     addr_t lr;     // next instruction address
2026     addr_t target; // target address
2027     int32_t imm32; // PC-relative offset
2028     switch (encoding) {
2029     case eEncodingT1: {
2030       lr = pc | 1u; // return address
2031       uint32_t S = Bit32(opcode, 26);
2032       uint32_t imm10 = Bits32(opcode, 25, 16);
2033       uint32_t J1 = Bit32(opcode, 13);
2034       uint32_t J2 = Bit32(opcode, 11);
2035       uint32_t imm11 = Bits32(opcode, 10, 0);
2036       uint32_t I1 = !(J1 ^ S);
2037       uint32_t I2 = !(J2 ^ S);
2038       uint32_t imm25 =
2039           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2040       imm32 = llvm::SignExtend32<25>(imm25);
2041       target = pc + imm32;
2042       SelectInstrSet(eModeThumb);
2043       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2044       if (InITBlock() && !LastInITBlock())
2045         return false;
2046       break;
2047     }
2048     case eEncodingT2: {
2049       lr = pc | 1u; // return address
2050       uint32_t S = Bit32(opcode, 26);
2051       uint32_t imm10H = Bits32(opcode, 25, 16);
2052       uint32_t J1 = Bit32(opcode, 13);
2053       uint32_t J2 = Bit32(opcode, 11);
2054       uint32_t imm10L = Bits32(opcode, 10, 1);
2055       uint32_t I1 = !(J1 ^ S);
2056       uint32_t I2 = !(J2 ^ S);
2057       uint32_t imm25 =
2058           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2059       imm32 = llvm::SignExtend32<25>(imm25);
2060       target = Align(pc, 4) + imm32;
2061       SelectInstrSet(eModeARM);
2062       context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2063       if (InITBlock() && !LastInITBlock())
2064         return false;
2065       break;
2066     }
2067     case eEncodingA1:
2068       lr = pc - 4; // return address
2069       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2070       target = Align(pc, 4) + imm32;
2071       SelectInstrSet(eModeARM);
2072       context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2073       break;
2074     case eEncodingA2:
2075       lr = pc - 4; // return address
2076       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2077                                      Bits32(opcode, 24, 24) << 1);
2078       target = pc + imm32;
2079       SelectInstrSet(eModeThumb);
2080       context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2081       break;
2082     default:
2083       return false;
2084     }
2085     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2086                                LLDB_REGNUM_GENERIC_RA, lr))
2087       return false;
2088     if (!BranchWritePC(context, target))
2089       return false;
2090     if (m_opcode_cpsr != m_new_inst_cpsr)
2091       if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2092                                  LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2093         return false;
2094   }
2095   return true;
2096 }
2097 
2098 // Branch with Link and Exchange (register) calls a subroutine at an address
2099 // and instruction set specified by a register.
2100 // BLX (register)
2101 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2102                                          const ARMEncoding encoding) {
2103 #if 0
2104     // ARM pseudo code...
2105     if (ConditionPassed())
2106     {
2107         EncodingSpecificOperations();
2108         target = R[m];
2109         if CurrentInstrSet() == InstrSet_ARM then
2110             next_instr_addr = PC - 4;
2111             LR = next_instr_addr;
2112         else
2113             next_instr_addr = PC - 2;
2114             LR = next_instr_addr<31:1> : '1';
2115         BXWritePC(target);
2116     }
2117 #endif
2118 
2119   bool success = false;
2120 
2121   if (ConditionPassed(opcode)) {
2122     EmulateInstruction::Context context;
2123     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2124     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2125     addr_t lr; // next instruction address
2126     if (!success)
2127       return false;
2128     uint32_t Rm; // the register with the target address
2129     switch (encoding) {
2130     case eEncodingT1:
2131       lr = (pc - 2) | 1u; // return address
2132       Rm = Bits32(opcode, 6, 3);
2133       // if m == 15 then UNPREDICTABLE;
2134       if (Rm == 15)
2135         return false;
2136       if (InITBlock() && !LastInITBlock())
2137         return false;
2138       break;
2139     case eEncodingA1:
2140       lr = pc - 4; // return address
2141       Rm = Bits32(opcode, 3, 0);
2142       // if m == 15 then UNPREDICTABLE;
2143       if (Rm == 15)
2144         return false;
2145       break;
2146     default:
2147       return false;
2148     }
2149     addr_t target = ReadCoreReg(Rm, &success);
2150     if (!success)
2151       return false;
2152     std::optional<RegisterInfo> dwarf_reg =
2153         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2154     context.SetRegister(*dwarf_reg);
2155     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2156                                LLDB_REGNUM_GENERIC_RA, lr))
2157       return false;
2158     if (!BXWritePC(context, target))
2159       return false;
2160   }
2161   return true;
2162 }
2163 
2164 // Branch and Exchange causes a branch to an address and instruction set
2165 // specified by a register.
2166 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2167                                         const ARMEncoding encoding) {
2168 #if 0
2169     // ARM pseudo code...
2170     if (ConditionPassed())
2171     {
2172         EncodingSpecificOperations();
2173         BXWritePC(R[m]);
2174     }
2175 #endif
2176 
2177   if (ConditionPassed(opcode)) {
2178     EmulateInstruction::Context context;
2179     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2180     uint32_t Rm; // the register with the target address
2181     switch (encoding) {
2182     case eEncodingT1:
2183       Rm = Bits32(opcode, 6, 3);
2184       if (InITBlock() && !LastInITBlock())
2185         return false;
2186       break;
2187     case eEncodingA1:
2188       Rm = Bits32(opcode, 3, 0);
2189       break;
2190     default:
2191       return false;
2192     }
2193     bool success = false;
2194     addr_t target = ReadCoreReg(Rm, &success);
2195     if (!success)
2196       return false;
2197 
2198     std::optional<RegisterInfo> dwarf_reg =
2199         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2200     context.SetRegister(*dwarf_reg);
2201     if (!BXWritePC(context, target))
2202       return false;
2203   }
2204   return true;
2205 }
2206 
2207 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2208 // attempt fails, it branches to an address and instruction set specified by a
2209 // register as though it were a BX instruction.
2210 //
2211 // TODO: Emulate Jazelle architecture?
2212 //       We currently assume that switching to Jazelle state fails, thus
2213 //       treating BXJ as a BX operation.
2214 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2215                                          const ARMEncoding encoding) {
2216 #if 0
2217     // ARM pseudo code...
2218     if (ConditionPassed())
2219     {
2220         EncodingSpecificOperations();
2221         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2222             BXWritePC(R[m]);
2223         else
2224             if JazelleAcceptsExecution() then
2225                 SwitchToJazelleExecution();
2226             else
2227                 SUBARCHITECTURE_DEFINED handler call;
2228     }
2229 #endif
2230 
2231   if (ConditionPassed(opcode)) {
2232     EmulateInstruction::Context context;
2233     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2234     uint32_t Rm; // the register with the target address
2235     switch (encoding) {
2236     case eEncodingT1:
2237       Rm = Bits32(opcode, 19, 16);
2238       if (BadReg(Rm))
2239         return false;
2240       if (InITBlock() && !LastInITBlock())
2241         return false;
2242       break;
2243     case eEncodingA1:
2244       Rm = Bits32(opcode, 3, 0);
2245       if (Rm == 15)
2246         return false;
2247       break;
2248     default:
2249       return false;
2250     }
2251     bool success = false;
2252     addr_t target = ReadCoreReg(Rm, &success);
2253     if (!success)
2254       return false;
2255 
2256     std::optional<RegisterInfo> dwarf_reg =
2257         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2258     context.SetRegister(*dwarf_reg);
2259     if (!BXWritePC(context, target))
2260       return false;
2261   }
2262   return true;
2263 }
2264 
2265 // Set r7 to point to some ip offset.
2266 // SUB (immediate)
2267 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2268                                               const ARMEncoding encoding) {
2269 #if 0
2270     // ARM pseudo code...
2271     if (ConditionPassed())
2272     {
2273         EncodingSpecificOperations();
2274         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2275         if d == 15 then // Can only occur for ARM encoding
2276            ALUWritePC(result); // setflags is always FALSE here
2277         else
2278             R[d] = result;
2279             if setflags then
2280                 APSR.N = result<31>;
2281                 APSR.Z = IsZeroBit(result);
2282                 APSR.C = carry;
2283                 APSR.V = overflow;
2284     }
2285 #endif
2286 
2287   if (ConditionPassed(opcode)) {
2288     bool success = false;
2289     const addr_t ip = ReadCoreReg(12, &success);
2290     if (!success)
2291       return false;
2292     uint32_t imm32;
2293     switch (encoding) {
2294     case eEncodingA1:
2295       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2296       break;
2297     default:
2298       return false;
2299     }
2300     addr_t ip_offset = imm32;
2301     addr_t addr = ip - ip_offset; // the adjusted ip value
2302 
2303     EmulateInstruction::Context context;
2304     context.type = EmulateInstruction::eContextRegisterPlusOffset;
2305     std::optional<RegisterInfo> dwarf_reg =
2306         GetRegisterInfo(eRegisterKindDWARF, dwarf_r12);
2307     context.SetRegisterPlusOffset(*dwarf_reg, -ip_offset);
2308 
2309     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2310       return false;
2311   }
2312   return true;
2313 }
2314 
2315 // Set ip to point to some stack offset.
2316 // SUB (SP minus immediate)
2317 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2318                                               const ARMEncoding encoding) {
2319 #if 0
2320     // ARM pseudo code...
2321     if (ConditionPassed())
2322     {
2323         EncodingSpecificOperations();
2324         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2325         if d == 15 then // Can only occur for ARM encoding
2326            ALUWritePC(result); // setflags is always FALSE here
2327         else
2328             R[d] = result;
2329             if setflags then
2330                 APSR.N = result<31>;
2331                 APSR.Z = IsZeroBit(result);
2332                 APSR.C = carry;
2333                 APSR.V = overflow;
2334     }
2335 #endif
2336 
2337   if (ConditionPassed(opcode)) {
2338     bool success = false;
2339     const addr_t sp = ReadCoreReg(SP_REG, &success);
2340     if (!success)
2341       return false;
2342     uint32_t imm32;
2343     switch (encoding) {
2344     case eEncodingA1:
2345       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2346       break;
2347     default:
2348       return false;
2349     }
2350     addr_t sp_offset = imm32;
2351     addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2352 
2353     EmulateInstruction::Context context;
2354     context.type = EmulateInstruction::eContextRegisterPlusOffset;
2355     std::optional<RegisterInfo> dwarf_reg =
2356         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
2357     context.SetRegisterPlusOffset(*dwarf_reg, -sp_offset);
2358 
2359     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2360       return false;
2361   }
2362   return true;
2363 }
2364 
2365 // This instruction subtracts an immediate value from the SP value, and writes
2366 // the result to the destination register.
2367 //
2368 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2369 // storage.
2370 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2371                                             const ARMEncoding encoding) {
2372 #if 0
2373     // ARM pseudo code...
2374     if (ConditionPassed())
2375     {
2376         EncodingSpecificOperations();
2377         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2378         if d == 15 then        // Can only occur for ARM encoding
2379            ALUWritePC(result); // setflags is always FALSE here
2380         else
2381             R[d] = result;
2382             if setflags then
2383                 APSR.N = result<31>;
2384                 APSR.Z = IsZeroBit(result);
2385                 APSR.C = carry;
2386                 APSR.V = overflow;
2387     }
2388 #endif
2389 
2390   bool success = false;
2391   if (ConditionPassed(opcode)) {
2392     const addr_t sp = ReadCoreReg(SP_REG, &success);
2393     if (!success)
2394       return false;
2395 
2396     uint32_t Rd;
2397     bool setflags;
2398     uint32_t imm32;
2399     switch (encoding) {
2400     case eEncodingT1:
2401       Rd = 13;
2402       setflags = false;
2403       imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2404       break;
2405     case eEncodingT2:
2406       Rd = Bits32(opcode, 11, 8);
2407       setflags = BitIsSet(opcode, 20);
2408       imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2409       if (Rd == 15 && setflags)
2410         return EmulateCMPImm(opcode, eEncodingT2);
2411       if (Rd == 15 && !setflags)
2412         return false;
2413       break;
2414     case eEncodingT3:
2415       Rd = Bits32(opcode, 11, 8);
2416       setflags = false;
2417       imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2418       if (Rd == 15)
2419         return false;
2420       break;
2421     case eEncodingA1:
2422       Rd = Bits32(opcode, 15, 12);
2423       setflags = BitIsSet(opcode, 20);
2424       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2425 
2426       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2427       // instructions;
2428       if (Rd == 15 && setflags)
2429         return EmulateSUBSPcLrEtc(opcode, encoding);
2430       break;
2431     default:
2432       return false;
2433     }
2434     AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2435 
2436     EmulateInstruction::Context context;
2437     if (Rd == 13) {
2438       uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2439                               // to negate it, or the wrong
2440       // value gets passed down to context.SetImmediateSigned.
2441       context.type = EmulateInstruction::eContextAdjustStackPointer;
2442       context.SetImmediateSigned(-imm64); // the stack pointer offset
2443     } else {
2444       context.type = EmulateInstruction::eContextImmediate;
2445       context.SetNoArgs();
2446     }
2447 
2448     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2449                                    res.carry_out, res.overflow))
2450       return false;
2451   }
2452   return true;
2453 }
2454 
2455 // A store operation to the stack that also updates the SP.
2456 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2457                                            const ARMEncoding encoding) {
2458 #if 0
2459     // ARM pseudo code...
2460     if (ConditionPassed())
2461     {
2462         EncodingSpecificOperations();
2463         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2464         address = if index then offset_addr else R[n];
2465         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2466         if wback then R[n] = offset_addr;
2467     }
2468 #endif
2469 
2470   bool success = false;
2471   if (ConditionPassed(opcode)) {
2472     const uint32_t addr_byte_size = GetAddressByteSize();
2473     const addr_t sp = ReadCoreReg(SP_REG, &success);
2474     if (!success)
2475       return false;
2476     uint32_t Rt; // the source register
2477     uint32_t imm12;
2478     uint32_t
2479         Rn; // This function assumes Rn is the SP, but we should verify that.
2480 
2481     bool index;
2482     bool add;
2483     bool wback;
2484     switch (encoding) {
2485     case eEncodingA1:
2486       Rt = Bits32(opcode, 15, 12);
2487       imm12 = Bits32(opcode, 11, 0);
2488       Rn = Bits32(opcode, 19, 16);
2489 
2490       if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2491         return false;
2492 
2493       index = BitIsSet(opcode, 24);
2494       add = BitIsSet(opcode, 23);
2495       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2496 
2497       if (wback && ((Rn == 15) || (Rn == Rt)))
2498         return false;
2499       break;
2500     default:
2501       return false;
2502     }
2503     addr_t offset_addr;
2504     if (add)
2505       offset_addr = sp + imm12;
2506     else
2507       offset_addr = sp - imm12;
2508 
2509     addr_t addr;
2510     if (index)
2511       addr = offset_addr;
2512     else
2513       addr = sp;
2514 
2515     EmulateInstruction::Context context;
2516     context.type = EmulateInstruction::eContextPushRegisterOnStack;
2517     std::optional<RegisterInfo> sp_reg =
2518         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
2519     std::optional<RegisterInfo> dwarf_reg =
2520         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt);
2521 
2522     context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2523     if (Rt != 15) {
2524       uint32_t reg_value = ReadCoreReg(Rt, &success);
2525       if (!success)
2526         return false;
2527       if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2528         return false;
2529     } else {
2530       const uint32_t pc = ReadCoreReg(PC_REG, &success);
2531       if (!success)
2532         return false;
2533       if (!MemUWrite(context, addr, pc, addr_byte_size))
2534         return false;
2535     }
2536 
2537     if (wback) {
2538       context.type = EmulateInstruction::eContextAdjustStackPointer;
2539       context.SetImmediateSigned(addr - sp);
2540       if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2541                                  LLDB_REGNUM_GENERIC_SP, offset_addr))
2542         return false;
2543     }
2544   }
2545   return true;
2546 }
2547 
2548 // Vector Push stores multiple extension registers to the stack. It also
2549 // updates SP to point to the start of the stored data.
2550 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2551                                          const ARMEncoding encoding) {
2552 #if 0
2553     // ARM pseudo code...
2554     if (ConditionPassed())
2555     {
2556         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2557         address = SP - imm32;
2558         SP = SP - imm32;
2559         if single_regs then
2560             for r = 0 to regs-1
2561                 MemA[address,4] = S[d+r]; address = address+4;
2562         else
2563             for r = 0 to regs-1
2564                 // Store as two word-aligned words in the correct order for
2565                 // current endianness.
2566                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2567                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2568                 address = address+8;
2569     }
2570 #endif
2571 
2572   bool success = false;
2573   if (ConditionPassed(opcode)) {
2574     const uint32_t addr_byte_size = GetAddressByteSize();
2575     const addr_t sp = ReadCoreReg(SP_REG, &success);
2576     if (!success)
2577       return false;
2578     bool single_regs;
2579     uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2580     uint32_t imm32; // stack offset
2581     uint32_t regs;  // number of registers
2582     switch (encoding) {
2583     case eEncodingT1:
2584     case eEncodingA1:
2585       single_regs = false;
2586       d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2587       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2588       // If UInt(imm8) is odd, see "FSTMX".
2589       regs = Bits32(opcode, 7, 0) / 2;
2590       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2591       if (regs == 0 || regs > 16 || (d + regs) > 32)
2592         return false;
2593       break;
2594     case eEncodingT2:
2595     case eEncodingA2:
2596       single_regs = true;
2597       d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2598       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2599       regs = Bits32(opcode, 7, 0);
2600       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2601       if (regs == 0 || regs > 16 || (d + regs) > 32)
2602         return false;
2603       break;
2604     default:
2605       return false;
2606     }
2607     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2608     uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2609     addr_t sp_offset = imm32;
2610     addr_t addr = sp - sp_offset;
2611     uint32_t i;
2612 
2613     EmulateInstruction::Context context;
2614     context.type = EmulateInstruction::eContextPushRegisterOnStack;
2615 
2616     std::optional<RegisterInfo> sp_reg =
2617         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
2618     for (i = 0; i < regs; ++i) {
2619       std::optional<RegisterInfo> dwarf_reg =
2620           GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2621       context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2622       // uint64_t to accommodate 64-bit registers.
2623       uint64_t reg_value = ReadRegisterUnsigned(*dwarf_reg, 0, &success);
2624       if (!success)
2625         return false;
2626       if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2627         return false;
2628       addr += reg_byte_size;
2629     }
2630 
2631     context.type = EmulateInstruction::eContextAdjustStackPointer;
2632     context.SetImmediateSigned(-sp_offset);
2633 
2634     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2635                                LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2636       return false;
2637   }
2638   return true;
2639 }
2640 
2641 // Vector Pop loads multiple extension registers from the stack. It also
2642 // updates SP to point just above the loaded data.
2643 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2644                                         const ARMEncoding encoding) {
2645 #if 0
2646     // ARM pseudo code...
2647     if (ConditionPassed())
2648     {
2649         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2650         address = SP;
2651         SP = SP + imm32;
2652         if single_regs then
2653             for r = 0 to regs-1
2654                 S[d+r] = MemA[address,4]; address = address+4;
2655         else
2656             for r = 0 to regs-1
2657                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2658                 // Combine the word-aligned words in the correct order for
2659                 // current endianness.
2660                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2661     }
2662 #endif
2663 
2664   bool success = false;
2665   if (ConditionPassed(opcode)) {
2666     const uint32_t addr_byte_size = GetAddressByteSize();
2667     const addr_t sp = ReadCoreReg(SP_REG, &success);
2668     if (!success)
2669       return false;
2670     bool single_regs;
2671     uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2672     uint32_t imm32; // stack offset
2673     uint32_t regs;  // number of registers
2674     switch (encoding) {
2675     case eEncodingT1:
2676     case eEncodingA1:
2677       single_regs = false;
2678       d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2679       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2680       // If UInt(imm8) is odd, see "FLDMX".
2681       regs = Bits32(opcode, 7, 0) / 2;
2682       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2683       if (regs == 0 || regs > 16 || (d + regs) > 32)
2684         return false;
2685       break;
2686     case eEncodingT2:
2687     case eEncodingA2:
2688       single_regs = true;
2689       d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2690       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2691       regs = Bits32(opcode, 7, 0);
2692       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2693       if (regs == 0 || regs > 16 || (d + regs) > 32)
2694         return false;
2695       break;
2696     default:
2697       return false;
2698     }
2699     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2700     uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2701     addr_t sp_offset = imm32;
2702     addr_t addr = sp;
2703     uint32_t i;
2704     uint64_t data; // uint64_t to accommodate 64-bit registers.
2705 
2706     EmulateInstruction::Context context;
2707     context.type = EmulateInstruction::eContextPopRegisterOffStack;
2708 
2709     for (i = 0; i < regs; ++i) {
2710       std::optional<RegisterInfo> dwarf_reg =
2711           GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2712       context.SetAddress(addr);
2713       data = MemARead(context, addr, reg_byte_size, 0, &success);
2714       if (!success)
2715         return false;
2716       if (!WriteRegisterUnsigned(context, *dwarf_reg, data))
2717         return false;
2718       addr += reg_byte_size;
2719     }
2720 
2721     context.type = EmulateInstruction::eContextAdjustStackPointer;
2722     context.SetImmediateSigned(sp_offset);
2723 
2724     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2725                                LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2726       return false;
2727   }
2728   return true;
2729 }
2730 
2731 // SVC (previously SWI)
2732 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2733                                        const ARMEncoding encoding) {
2734 #if 0
2735     // ARM pseudo code...
2736     if (ConditionPassed())
2737     {
2738         EncodingSpecificOperations();
2739         CallSupervisor();
2740     }
2741 #endif
2742 
2743   bool success = false;
2744 
2745   if (ConditionPassed(opcode)) {
2746     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2747     addr_t lr; // next instruction address
2748     if (!success)
2749       return false;
2750     uint32_t imm32; // the immediate constant
2751     uint32_t mode;  // ARM or Thumb mode
2752     switch (encoding) {
2753     case eEncodingT1:
2754       lr = (pc + 2) | 1u; // return address
2755       imm32 = Bits32(opcode, 7, 0);
2756       mode = eModeThumb;
2757       break;
2758     case eEncodingA1:
2759       lr = pc + 4; // return address
2760       imm32 = Bits32(opcode, 23, 0);
2761       mode = eModeARM;
2762       break;
2763     default:
2764       return false;
2765     }
2766 
2767     EmulateInstruction::Context context;
2768     context.type = EmulateInstruction::eContextSupervisorCall;
2769     context.SetISAAndImmediate(mode, imm32);
2770     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2771                                LLDB_REGNUM_GENERIC_RA, lr))
2772       return false;
2773   }
2774   return true;
2775 }
2776 
2777 // If Then makes up to four following instructions (the IT block) conditional.
2778 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2779                                       const ARMEncoding encoding) {
2780 #if 0
2781     // ARM pseudo code...
2782     EncodingSpecificOperations();
2783     ITSTATE.IT<7:0> = firstcond:mask;
2784 #endif
2785 
2786   m_it_session.InitIT(Bits32(opcode, 7, 0));
2787   return true;
2788 }
2789 
2790 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2791                                        const ARMEncoding encoding) {
2792   // NOP, nothing to do...
2793   return true;
2794 }
2795 
2796 // Branch causes a branch to a target address.
2797 bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2798                                      const ARMEncoding encoding) {
2799 #if 0
2800     // ARM pseudo code...
2801     if (ConditionPassed())
2802     {
2803         EncodingSpecificOperations();
2804         BranchWritePC(PC + imm32);
2805     }
2806 #endif
2807 
2808   bool success = false;
2809 
2810   if (ConditionPassed(opcode)) {
2811     EmulateInstruction::Context context;
2812     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2813     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2814     if (!success)
2815       return false;
2816     addr_t target; // target address
2817     int32_t imm32; // PC-relative offset
2818     switch (encoding) {
2819     case eEncodingT1:
2820       // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2821       imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2822       target = pc + imm32;
2823       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2824       break;
2825     case eEncodingT2:
2826       imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2827       target = pc + imm32;
2828       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2829       break;
2830     case eEncodingT3:
2831       // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2832       {
2833         if (Bits32(opcode, 25, 23) == 7)
2834           return false; // See Branches and miscellaneous control on page
2835                         // A6-235.
2836 
2837         uint32_t S = Bit32(opcode, 26);
2838         uint32_t imm6 = Bits32(opcode, 21, 16);
2839         uint32_t J1 = Bit32(opcode, 13);
2840         uint32_t J2 = Bit32(opcode, 11);
2841         uint32_t imm11 = Bits32(opcode, 10, 0);
2842         uint32_t imm21 =
2843             (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2844         imm32 = llvm::SignExtend32<21>(imm21);
2845         target = pc + imm32;
2846         context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2847         break;
2848       }
2849     case eEncodingT4: {
2850       uint32_t S = Bit32(opcode, 26);
2851       uint32_t imm10 = Bits32(opcode, 25, 16);
2852       uint32_t J1 = Bit32(opcode, 13);
2853       uint32_t J2 = Bit32(opcode, 11);
2854       uint32_t imm11 = Bits32(opcode, 10, 0);
2855       uint32_t I1 = !(J1 ^ S);
2856       uint32_t I2 = !(J2 ^ S);
2857       uint32_t imm25 =
2858           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2859       imm32 = llvm::SignExtend32<25>(imm25);
2860       target = pc + imm32;
2861       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2862       break;
2863     }
2864     case eEncodingA1:
2865       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2866       target = pc + imm32;
2867       context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2868       break;
2869     default:
2870       return false;
2871     }
2872     if (!BranchWritePC(context, target))
2873       return false;
2874   }
2875   return true;
2876 }
2877 
2878 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2879 // value in a register with zero and conditionally branch forward a constant
2880 // value.  They do not affect the condition flags. CBNZ, CBZ
2881 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2882                                       const ARMEncoding encoding) {
2883 #if 0
2884     // ARM pseudo code...
2885     EncodingSpecificOperations();
2886     if nonzero ^ IsZero(R[n]) then
2887         BranchWritePC(PC + imm32);
2888 #endif
2889 
2890   bool success = false;
2891 
2892   // Read the register value from the operand register Rn.
2893   uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2894   if (!success)
2895     return false;
2896 
2897   EmulateInstruction::Context context;
2898   context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2899   const uint32_t pc = ReadCoreReg(PC_REG, &success);
2900   if (!success)
2901     return false;
2902 
2903   addr_t target;  // target address
2904   uint32_t imm32; // PC-relative offset to branch forward
2905   bool nonzero;
2906   switch (encoding) {
2907   case eEncodingT1:
2908     imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2909     nonzero = BitIsSet(opcode, 11);
2910     target = pc + imm32;
2911     context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2912     break;
2913   default:
2914     return false;
2915   }
2916   if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2917     if (!BranchWritePC(context, target))
2918       return false;
2919 
2920   return true;
2921 }
2922 
2923 // Table Branch Byte causes a PC-relative forward branch using a table of
2924 // single byte offsets.
2925 // A base register provides a pointer to the table, and a second register
2926 // supplies an index into the table.
2927 // The branch length is twice the value of the byte returned from the table.
2928 //
2929 // Table Branch Halfword causes a PC-relative forward branch using a table of
2930 // single halfword offsets.
2931 // A base register provides a pointer to the table, and a second register
2932 // supplies an index into the table.
2933 // The branch length is twice the value of the halfword returned from the
2934 // table. TBB, TBH
2935 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2936                                       const ARMEncoding encoding) {
2937 #if 0
2938     // ARM pseudo code...
2939     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2940     if is_tbh then
2941         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2942     else
2943         halfwords = UInt(MemU[R[n]+R[m], 1]);
2944     BranchWritePC(PC + 2*halfwords);
2945 #endif
2946 
2947   bool success = false;
2948 
2949   if (ConditionPassed(opcode)) {
2950     uint32_t Rn; // the base register which contains the address of the table of
2951                  // branch lengths
2952     uint32_t Rm; // the index register which contains an integer pointing to a
2953                  // byte/halfword in the table
2954     bool is_tbh; // true if table branch halfword
2955     switch (encoding) {
2956     case eEncodingT1:
2957       Rn = Bits32(opcode, 19, 16);
2958       Rm = Bits32(opcode, 3, 0);
2959       is_tbh = BitIsSet(opcode, 4);
2960       if (Rn == 13 || BadReg(Rm))
2961         return false;
2962       if (InITBlock() && !LastInITBlock())
2963         return false;
2964       break;
2965     default:
2966       return false;
2967     }
2968 
2969     // Read the address of the table from the operand register Rn. The PC can
2970     // be used, in which case the table immediately follows this instruction.
2971     uint32_t base = ReadCoreReg(Rn, &success);
2972     if (!success)
2973       return false;
2974 
2975     // the table index
2976     uint32_t index = ReadCoreReg(Rm, &success);
2977     if (!success)
2978       return false;
2979 
2980     // the offsetted table address
2981     addr_t addr = base + (is_tbh ? index * 2 : index);
2982 
2983     // PC-relative offset to branch forward
2984     EmulateInstruction::Context context;
2985     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2986     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2987     if (!success)
2988       return false;
2989 
2990     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2991     if (!success)
2992       return false;
2993 
2994     // target address
2995     addr_t target = pc + offset;
2996     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2997     context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
2998 
2999     if (!BranchWritePC(context, target))
3000       return false;
3001   }
3002 
3003   return true;
3004 }
3005 
3006 // This instruction adds an immediate value to a register value, and writes the
3007 // result to the destination register. It can optionally update the condition
3008 // flags based on the result.
3009 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3010                                                const ARMEncoding encoding) {
3011 #if 0
3012     if ConditionPassed() then
3013         EncodingSpecificOperations();
3014         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3015         R[d] = result;
3016         if setflags then
3017             APSR.N = result<31>;
3018             APSR.Z = IsZeroBit(result);
3019             APSR.C = carry;
3020             APSR.V = overflow;
3021 #endif
3022 
3023   bool success = false;
3024 
3025   if (ConditionPassed(opcode)) {
3026     uint32_t d;
3027     uint32_t n;
3028     bool setflags;
3029     uint32_t imm32;
3030     uint32_t carry_out;
3031 
3032     // EncodingSpecificOperations();
3033     switch (encoding) {
3034     case eEncodingT1:
3035       // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3036       // ZeroExtend(imm3, 32);
3037       d = Bits32(opcode, 2, 0);
3038       n = Bits32(opcode, 5, 3);
3039       setflags = !InITBlock();
3040       imm32 = Bits32(opcode, 8, 6);
3041 
3042       break;
3043 
3044     case eEncodingT2:
3045       // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3046       // ZeroExtend(imm8, 32);
3047       d = Bits32(opcode, 10, 8);
3048       n = Bits32(opcode, 10, 8);
3049       setflags = !InITBlock();
3050       imm32 = Bits32(opcode, 7, 0);
3051 
3052       break;
3053 
3054     case eEncodingT3:
3055       // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3056       // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3057       // ThumbExpandImm(i:imm3:imm8);
3058       d = Bits32(opcode, 11, 8);
3059       n = Bits32(opcode, 19, 16);
3060       setflags = BitIsSet(opcode, 20);
3061       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3062 
3063       // if Rn == '1101' then SEE ADD (SP plus immediate);
3064       if (n == 13)
3065         return EmulateADDSPImm(opcode, eEncodingT3);
3066 
3067       // if BadReg(d) || n == 15 then UNPREDICTABLE;
3068       if (BadReg(d) || (n == 15))
3069         return false;
3070 
3071       break;
3072 
3073     case eEncodingT4: {
3074       // if Rn == '1111' then SEE ADR;
3075       // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3076       // ZeroExtend(i:imm3:imm8, 32);
3077       d = Bits32(opcode, 11, 8);
3078       n = Bits32(opcode, 19, 16);
3079       setflags = false;
3080       uint32_t i = Bit32(opcode, 26);
3081       uint32_t imm3 = Bits32(opcode, 14, 12);
3082       uint32_t imm8 = Bits32(opcode, 7, 0);
3083       imm32 = (i << 11) | (imm3 << 8) | imm8;
3084 
3085       // if Rn == '1101' then SEE ADD (SP plus immediate);
3086       if (n == 13)
3087         return EmulateADDSPImm(opcode, eEncodingT4);
3088 
3089       // if BadReg(d) then UNPREDICTABLE;
3090       if (BadReg(d))
3091         return false;
3092 
3093       break;
3094     }
3095 
3096     default:
3097       return false;
3098     }
3099 
3100     uint64_t Rn =
3101         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3102     if (!success)
3103       return false;
3104 
3105     //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3106     AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3107 
3108     std::optional<RegisterInfo> reg_n =
3109         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
3110     EmulateInstruction::Context context;
3111     context.type = eContextArithmetic;
3112     context.SetRegisterPlusOffset(*reg_n, imm32);
3113 
3114     // R[d] = result;
3115     // if setflags then
3116     // APSR.N = result<31>;
3117     // APSR.Z = IsZeroBit(result);
3118     // APSR.C = carry;
3119     // APSR.V = overflow;
3120     if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3121                                    res.carry_out, res.overflow))
3122       return false;
3123   }
3124   return true;
3125 }
3126 
3127 // This instruction adds an immediate value to a register value, and writes the
3128 // result to the destination register.  It can optionally update the condition
3129 // flags based on the result.
3130 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3131                                              const ARMEncoding encoding) {
3132 #if 0
3133     // ARM pseudo code...
3134     if ConditionPassed() then
3135         EncodingSpecificOperations();
3136         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3137         if d == 15 then
3138             ALUWritePC(result); // setflags is always FALSE here
3139         else
3140             R[d] = result;
3141             if setflags then
3142                 APSR.N = result<31>;
3143                 APSR.Z = IsZeroBit(result);
3144                 APSR.C = carry;
3145                 APSR.V = overflow;
3146 #endif
3147 
3148   bool success = false;
3149 
3150   if (ConditionPassed(opcode)) {
3151     uint32_t Rd, Rn;
3152     uint32_t
3153         imm32; // the immediate value to be added to the value obtained from Rn
3154     bool setflags;
3155     switch (encoding) {
3156     case eEncodingA1:
3157       Rd = Bits32(opcode, 15, 12);
3158       Rn = Bits32(opcode, 19, 16);
3159       setflags = BitIsSet(opcode, 20);
3160       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3161       break;
3162     default:
3163       return false;
3164     }
3165 
3166     // Read the first operand.
3167     uint32_t val1 = ReadCoreReg(Rn, &success);
3168     if (!success)
3169       return false;
3170 
3171     AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3172 
3173     EmulateInstruction::Context context;
3174     if (Rd == 13)
3175       context.type = EmulateInstruction::eContextAdjustStackPointer;
3176     else if (Rd == GetFramePointerRegisterNumber())
3177       context.type = EmulateInstruction::eContextSetFramePointer;
3178     else
3179       context.type = EmulateInstruction::eContextRegisterPlusOffset;
3180 
3181     std::optional<RegisterInfo> dwarf_reg =
3182         GetRegisterInfo(eRegisterKindDWARF, Rn);
3183     context.SetRegisterPlusOffset(*dwarf_reg, imm32);
3184 
3185     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3186                                    res.carry_out, res.overflow))
3187       return false;
3188   }
3189   return true;
3190 }
3191 
3192 // This instruction adds a register value and an optionally-shifted register
3193 // value, and writes the result to the destination register. It can optionally
3194 // update the condition flags based on the result.
3195 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3196                                           const ARMEncoding encoding) {
3197 #if 0
3198     // ARM pseudo code...
3199     if ConditionPassed() then
3200         EncodingSpecificOperations();
3201         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3202         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3203         if d == 15 then
3204             ALUWritePC(result); // setflags is always FALSE here
3205         else
3206             R[d] = result;
3207             if setflags then
3208                 APSR.N = result<31>;
3209                 APSR.Z = IsZeroBit(result);
3210                 APSR.C = carry;
3211                 APSR.V = overflow;
3212 #endif
3213 
3214   bool success = false;
3215 
3216   if (ConditionPassed(opcode)) {
3217     uint32_t Rd, Rn, Rm;
3218     ARM_ShifterType shift_t;
3219     uint32_t shift_n; // the shift applied to the value read from Rm
3220     bool setflags;
3221     switch (encoding) {
3222     case eEncodingT1:
3223       Rd = Bits32(opcode, 2, 0);
3224       Rn = Bits32(opcode, 5, 3);
3225       Rm = Bits32(opcode, 8, 6);
3226       setflags = !InITBlock();
3227       shift_t = SRType_LSL;
3228       shift_n = 0;
3229       break;
3230     case eEncodingT2:
3231       Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3232       Rm = Bits32(opcode, 6, 3);
3233       setflags = false;
3234       shift_t = SRType_LSL;
3235       shift_n = 0;
3236       if (Rn == 15 && Rm == 15)
3237         return false;
3238       if (Rd == 15 && InITBlock() && !LastInITBlock())
3239         return false;
3240       break;
3241     case eEncodingA1:
3242       Rd = Bits32(opcode, 15, 12);
3243       Rn = Bits32(opcode, 19, 16);
3244       Rm = Bits32(opcode, 3, 0);
3245       setflags = BitIsSet(opcode, 20);
3246       shift_n = DecodeImmShiftARM(opcode, shift_t);
3247       break;
3248     default:
3249       return false;
3250     }
3251 
3252     // Read the first operand.
3253     uint32_t val1 = ReadCoreReg(Rn, &success);
3254     if (!success)
3255       return false;
3256 
3257     // Read the second operand.
3258     uint32_t val2 = ReadCoreReg(Rm, &success);
3259     if (!success)
3260       return false;
3261 
3262     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3263     if (!success)
3264       return false;
3265     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3266 
3267     EmulateInstruction::Context context;
3268     context.type = eContextArithmetic;
3269     std::optional<RegisterInfo> op1_reg =
3270         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn);
3271     std::optional<RegisterInfo> op2_reg =
3272         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
3273     context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
3274 
3275     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3276                                    res.carry_out, res.overflow))
3277       return false;
3278   }
3279   return true;
3280 }
3281 
3282 // Compare Negative (immediate) adds a register value and an immediate value.
3283 // It updates the condition flags based on the result, and discards the result.
3284 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3285                                           const ARMEncoding encoding) {
3286 #if 0
3287     // ARM pseudo code...
3288     if ConditionPassed() then
3289         EncodingSpecificOperations();
3290         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3291         APSR.N = result<31>;
3292         APSR.Z = IsZeroBit(result);
3293         APSR.C = carry;
3294         APSR.V = overflow;
3295 #endif
3296 
3297   bool success = false;
3298 
3299   uint32_t Rn;    // the first operand
3300   uint32_t imm32; // the immediate value to be compared with
3301   switch (encoding) {
3302   case eEncodingT1:
3303     Rn = Bits32(opcode, 19, 16);
3304     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3305     if (Rn == 15)
3306       return false;
3307     break;
3308   case eEncodingA1:
3309     Rn = Bits32(opcode, 19, 16);
3310     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3311     break;
3312   default:
3313     return false;
3314   }
3315   // Read the register value from the operand register Rn.
3316   uint32_t reg_val = ReadCoreReg(Rn, &success);
3317   if (!success)
3318     return false;
3319 
3320   AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3321 
3322   EmulateInstruction::Context context;
3323   context.type = EmulateInstruction::eContextImmediate;
3324   context.SetNoArgs();
3325   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3326 }
3327 
3328 // Compare Negative (register) adds a register value and an optionally-shifted
3329 // register value. It updates the condition flags based on the result, and
3330 // discards the result.
3331 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3332                                           const ARMEncoding encoding) {
3333 #if 0
3334     // ARM pseudo code...
3335     if ConditionPassed() then
3336         EncodingSpecificOperations();
3337         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3338         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3339         APSR.N = result<31>;
3340         APSR.Z = IsZeroBit(result);
3341         APSR.C = carry;
3342         APSR.V = overflow;
3343 #endif
3344 
3345   bool success = false;
3346 
3347   uint32_t Rn; // the first operand
3348   uint32_t Rm; // the second operand
3349   ARM_ShifterType shift_t;
3350   uint32_t shift_n; // the shift applied to the value read from Rm
3351   switch (encoding) {
3352   case eEncodingT1:
3353     Rn = Bits32(opcode, 2, 0);
3354     Rm = Bits32(opcode, 5, 3);
3355     shift_t = SRType_LSL;
3356     shift_n = 0;
3357     break;
3358   case eEncodingT2:
3359     Rn = Bits32(opcode, 19, 16);
3360     Rm = Bits32(opcode, 3, 0);
3361     shift_n = DecodeImmShiftThumb(opcode, shift_t);
3362     // if n == 15 || BadReg(m) then UNPREDICTABLE;
3363     if (Rn == 15 || BadReg(Rm))
3364       return false;
3365     break;
3366   case eEncodingA1:
3367     Rn = Bits32(opcode, 19, 16);
3368     Rm = Bits32(opcode, 3, 0);
3369     shift_n = DecodeImmShiftARM(opcode, shift_t);
3370     break;
3371   default:
3372     return false;
3373   }
3374   // Read the register value from register Rn.
3375   uint32_t val1 = ReadCoreReg(Rn, &success);
3376   if (!success)
3377     return false;
3378 
3379   // Read the register value from register Rm.
3380   uint32_t val2 = ReadCoreReg(Rm, &success);
3381   if (!success)
3382     return false;
3383 
3384   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3385   if (!success)
3386     return false;
3387   AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3388 
3389   EmulateInstruction::Context context;
3390   context.type = EmulateInstruction::eContextImmediate;
3391   context.SetNoArgs();
3392   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3393 }
3394 
3395 // Compare (immediate) subtracts an immediate value from a register value. It
3396 // updates the condition flags based on the result, and discards the result.
3397 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3398                                           const ARMEncoding encoding) {
3399 #if 0
3400     // ARM pseudo code...
3401     if ConditionPassed() then
3402         EncodingSpecificOperations();
3403         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3404         APSR.N = result<31>;
3405         APSR.Z = IsZeroBit(result);
3406         APSR.C = carry;
3407         APSR.V = overflow;
3408 #endif
3409 
3410   bool success = false;
3411 
3412   uint32_t Rn;    // the first operand
3413   uint32_t imm32; // the immediate value to be compared with
3414   switch (encoding) {
3415   case eEncodingT1:
3416     Rn = Bits32(opcode, 10, 8);
3417     imm32 = Bits32(opcode, 7, 0);
3418     break;
3419   case eEncodingT2:
3420     Rn = Bits32(opcode, 19, 16);
3421     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3422     if (Rn == 15)
3423       return false;
3424     break;
3425   case eEncodingA1:
3426     Rn = Bits32(opcode, 19, 16);
3427     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3428     break;
3429   default:
3430     return false;
3431   }
3432   // Read the register value from the operand register Rn.
3433   uint32_t reg_val = ReadCoreReg(Rn, &success);
3434   if (!success)
3435     return false;
3436 
3437   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3438 
3439   EmulateInstruction::Context context;
3440   context.type = EmulateInstruction::eContextImmediate;
3441   context.SetNoArgs();
3442   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3443 }
3444 
3445 // Compare (register) subtracts an optionally-shifted register value from a
3446 // register value. It updates the condition flags based on the result, and
3447 // discards the result.
3448 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3449                                           const ARMEncoding encoding) {
3450 #if 0
3451     // ARM pseudo code...
3452     if ConditionPassed() then
3453         EncodingSpecificOperations();
3454         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3455         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3456         APSR.N = result<31>;
3457         APSR.Z = IsZeroBit(result);
3458         APSR.C = carry;
3459         APSR.V = overflow;
3460 #endif
3461 
3462   bool success = false;
3463 
3464   uint32_t Rn; // the first operand
3465   uint32_t Rm; // the second operand
3466   ARM_ShifterType shift_t;
3467   uint32_t shift_n; // the shift applied to the value read from Rm
3468   switch (encoding) {
3469   case eEncodingT1:
3470     Rn = Bits32(opcode, 2, 0);
3471     Rm = Bits32(opcode, 5, 3);
3472     shift_t = SRType_LSL;
3473     shift_n = 0;
3474     break;
3475   case eEncodingT2:
3476     Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3477     Rm = Bits32(opcode, 6, 3);
3478     shift_t = SRType_LSL;
3479     shift_n = 0;
3480     if (Rn < 8 && Rm < 8)
3481       return false;
3482     if (Rn == 15 || Rm == 15)
3483       return false;
3484     break;
3485   case eEncodingT3:
3486     Rn = Bits32(opcode, 19, 16);
3487     Rm = Bits32(opcode, 3, 0);
3488     shift_n = DecodeImmShiftThumb(opcode, shift_t);
3489     if (Rn == 15 || BadReg(Rm))
3490       return false;
3491     break;
3492   case eEncodingA1:
3493     Rn = Bits32(opcode, 19, 16);
3494     Rm = Bits32(opcode, 3, 0);
3495     shift_n = DecodeImmShiftARM(opcode, shift_t);
3496     break;
3497   default:
3498     return false;
3499   }
3500   // Read the register value from register Rn.
3501   uint32_t val1 = ReadCoreReg(Rn, &success);
3502   if (!success)
3503     return false;
3504 
3505   // Read the register value from register Rm.
3506   uint32_t val2 = ReadCoreReg(Rm, &success);
3507   if (!success)
3508     return false;
3509 
3510   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3511   if (!success)
3512     return false;
3513   AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3514 
3515   EmulateInstruction::Context context;
3516   context.type = EmulateInstruction::eContextImmediate;
3517   context.SetNoArgs();
3518   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3519 }
3520 
3521 // Arithmetic Shift Right (immediate) shifts a register value right by an
3522 // immediate number of bits, shifting in copies of its sign bit, and writes the
3523 // result to the destination register.  It can optionally update the condition
3524 // flags based on the result.
3525 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3526                                           const ARMEncoding encoding) {
3527 #if 0
3528     // ARM pseudo code...
3529     if ConditionPassed() then
3530         EncodingSpecificOperations();
3531         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3532         if d == 15 then         // Can only occur for ARM encoding
3533             ALUWritePC(result); // setflags is always FALSE here
3534         else
3535             R[d] = result;
3536             if setflags then
3537                 APSR.N = result<31>;
3538                 APSR.Z = IsZeroBit(result);
3539                 APSR.C = carry;
3540                 // APSR.V unchanged
3541 #endif
3542 
3543   return EmulateShiftImm(opcode, encoding, SRType_ASR);
3544 }
3545 
3546 // Arithmetic Shift Right (register) shifts a register value right by a
3547 // variable number of bits, shifting in copies of its sign bit, and writes the
3548 // result to the destination register. The variable number of bits is read from
3549 // the bottom byte of a register. It can optionally update the condition flags
3550 // based on the result.
3551 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3552                                           const ARMEncoding encoding) {
3553 #if 0
3554     // ARM pseudo code...
3555     if ConditionPassed() then
3556         EncodingSpecificOperations();
3557         shift_n = UInt(R[m]<7:0>);
3558         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3559         R[d] = result;
3560         if setflags then
3561             APSR.N = result<31>;
3562             APSR.Z = IsZeroBit(result);
3563             APSR.C = carry;
3564             // APSR.V unchanged
3565 #endif
3566 
3567   return EmulateShiftReg(opcode, encoding, SRType_ASR);
3568 }
3569 
3570 // Logical Shift Left (immediate) shifts a register value left by an immediate
3571 // number of bits, shifting in zeros, and writes the result to the destination
3572 // register.  It can optionally update the condition flags based on the result.
3573 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3574                                           const ARMEncoding encoding) {
3575 #if 0
3576     // ARM pseudo code...
3577     if ConditionPassed() then
3578         EncodingSpecificOperations();
3579         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3580         if d == 15 then         // Can only occur for ARM encoding
3581             ALUWritePC(result); // setflags is always FALSE here
3582         else
3583             R[d] = result;
3584             if setflags then
3585                 APSR.N = result<31>;
3586                 APSR.Z = IsZeroBit(result);
3587                 APSR.C = carry;
3588                 // APSR.V unchanged
3589 #endif
3590 
3591   return EmulateShiftImm(opcode, encoding, SRType_LSL);
3592 }
3593 
3594 // Logical Shift Left (register) shifts a register value left by a variable
3595 // number of bits, shifting in zeros, and writes the result to the destination
3596 // register.  The variable number of bits is read from the bottom byte of a
3597 // register. It can optionally update the condition flags based on the result.
3598 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3599                                           const ARMEncoding encoding) {
3600 #if 0
3601     // ARM pseudo code...
3602     if ConditionPassed() then
3603         EncodingSpecificOperations();
3604         shift_n = UInt(R[m]<7:0>);
3605         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3606         R[d] = result;
3607         if setflags then
3608             APSR.N = result<31>;
3609             APSR.Z = IsZeroBit(result);
3610             APSR.C = carry;
3611             // APSR.V unchanged
3612 #endif
3613 
3614   return EmulateShiftReg(opcode, encoding, SRType_LSL);
3615 }
3616 
3617 // Logical Shift Right (immediate) shifts a register value right by an
3618 // immediate number of bits, shifting in zeros, and writes the result to the
3619 // destination register.  It can optionally update the condition flags based on
3620 // the result.
3621 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3622                                           const ARMEncoding encoding) {
3623 #if 0
3624     // ARM pseudo code...
3625     if ConditionPassed() then
3626         EncodingSpecificOperations();
3627         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3628         if d == 15 then         // Can only occur for ARM encoding
3629             ALUWritePC(result); // setflags is always FALSE here
3630         else
3631             R[d] = result;
3632             if setflags then
3633                 APSR.N = result<31>;
3634                 APSR.Z = IsZeroBit(result);
3635                 APSR.C = carry;
3636                 // APSR.V unchanged
3637 #endif
3638 
3639   return EmulateShiftImm(opcode, encoding, SRType_LSR);
3640 }
3641 
3642 // Logical Shift Right (register) shifts a register value right by a variable
3643 // number of bits, shifting in zeros, and writes the result to the destination
3644 // register.  The variable number of bits is read from the bottom byte of a
3645 // register. It can optionally update the condition flags based on the result.
3646 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3647                                           const ARMEncoding encoding) {
3648 #if 0
3649     // ARM pseudo code...
3650     if ConditionPassed() then
3651         EncodingSpecificOperations();
3652         shift_n = UInt(R[m]<7:0>);
3653         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3654         R[d] = result;
3655         if setflags then
3656             APSR.N = result<31>;
3657             APSR.Z = IsZeroBit(result);
3658             APSR.C = carry;
3659             // APSR.V unchanged
3660 #endif
3661 
3662   return EmulateShiftReg(opcode, encoding, SRType_LSR);
3663 }
3664 
3665 // Rotate Right (immediate) provides the value of the contents of a register
3666 // rotated by a constant value. The bits that are rotated off the right end are
3667 // inserted into the vacated bit positions on the left. It can optionally
3668 // update the condition flags based on the result.
3669 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3670                                           const ARMEncoding encoding) {
3671 #if 0
3672     // ARM pseudo code...
3673     if ConditionPassed() then
3674         EncodingSpecificOperations();
3675         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3676         if d == 15 then         // Can only occur for ARM encoding
3677             ALUWritePC(result); // setflags is always FALSE here
3678         else
3679             R[d] = result;
3680             if setflags then
3681                 APSR.N = result<31>;
3682                 APSR.Z = IsZeroBit(result);
3683                 APSR.C = carry;
3684                 // APSR.V unchanged
3685 #endif
3686 
3687   return EmulateShiftImm(opcode, encoding, SRType_ROR);
3688 }
3689 
3690 // Rotate Right (register) provides the value of the contents of a register
3691 // rotated by a variable number of bits. The bits that are rotated off the
3692 // right end are inserted into the vacated bit positions on the left. The
3693 // variable number of bits is read from the bottom byte of a register. It can
3694 // optionally update the condition flags based on the result.
3695 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3696                                           const ARMEncoding encoding) {
3697 #if 0
3698     // ARM pseudo code...
3699     if ConditionPassed() then
3700         EncodingSpecificOperations();
3701         shift_n = UInt(R[m]<7:0>);
3702         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3703         R[d] = result;
3704         if setflags then
3705             APSR.N = result<31>;
3706             APSR.Z = IsZeroBit(result);
3707             APSR.C = carry;
3708             // APSR.V unchanged
3709 #endif
3710 
3711   return EmulateShiftReg(opcode, encoding, SRType_ROR);
3712 }
3713 
3714 // Rotate Right with Extend provides the value of the contents of a register
3715 // shifted right by one place, with the carry flag shifted into bit [31].
3716 //
3717 // RRX can optionally update the condition flags based on the result.
3718 // In that case, bit [0] is shifted into the carry flag.
3719 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3720                                        const ARMEncoding encoding) {
3721 #if 0
3722     // ARM pseudo code...
3723     if ConditionPassed() then
3724         EncodingSpecificOperations();
3725         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3726         if d == 15 then         // Can only occur for ARM encoding
3727             ALUWritePC(result); // setflags is always FALSE here
3728         else
3729             R[d] = result;
3730             if setflags then
3731                 APSR.N = result<31>;
3732                 APSR.Z = IsZeroBit(result);
3733                 APSR.C = carry;
3734                 // APSR.V unchanged
3735 #endif
3736 
3737   return EmulateShiftImm(opcode, encoding, SRType_RRX);
3738 }
3739 
3740 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3741                                             const ARMEncoding encoding,
3742                                             ARM_ShifterType shift_type) {
3743   //    assert(shift_type == SRType_ASR
3744   //           || shift_type == SRType_LSL
3745   //           || shift_type == SRType_LSR
3746   //           || shift_type == SRType_ROR
3747   //           || shift_type == SRType_RRX);
3748 
3749   bool success = false;
3750 
3751   if (ConditionPassed(opcode)) {
3752     uint32_t Rd;    // the destination register
3753     uint32_t Rm;    // the first operand register
3754     uint32_t imm5;  // encoding for the shift amount
3755     uint32_t carry; // the carry bit after the shift operation
3756     bool setflags;
3757 
3758     // Special case handling!
3759     // A8.6.139 ROR (immediate) -- Encoding T1
3760     ARMEncoding use_encoding = encoding;
3761     if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3762       // Morph the T1 encoding from the ARM Architecture Manual into T2
3763       // encoding to have the same decoding of bit fields as the other Thumb2
3764       // shift operations.
3765       use_encoding = eEncodingT2;
3766     }
3767 
3768     switch (use_encoding) {
3769     case eEncodingT1:
3770       Rd = Bits32(opcode, 2, 0);
3771       Rm = Bits32(opcode, 5, 3);
3772       setflags = !InITBlock();
3773       imm5 = Bits32(opcode, 10, 6);
3774       break;
3775     case eEncodingT2:
3776       // A8.6.141 RRX
3777       // There's no imm form of RRX instructions.
3778       if (shift_type == SRType_RRX)
3779         return false;
3780 
3781       Rd = Bits32(opcode, 11, 8);
3782       Rm = Bits32(opcode, 3, 0);
3783       setflags = BitIsSet(opcode, 20);
3784       imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3785       if (BadReg(Rd) || BadReg(Rm))
3786         return false;
3787       break;
3788     case eEncodingA1:
3789       Rd = Bits32(opcode, 15, 12);
3790       Rm = Bits32(opcode, 3, 0);
3791       setflags = BitIsSet(opcode, 20);
3792       imm5 = Bits32(opcode, 11, 7);
3793       break;
3794     default:
3795       return false;
3796     }
3797 
3798     // A8.6.139 ROR (immediate)
3799     if (shift_type == SRType_ROR && imm5 == 0)
3800       shift_type = SRType_RRX;
3801 
3802     // Get the first operand.
3803     uint32_t value = ReadCoreReg(Rm, &success);
3804     if (!success)
3805       return false;
3806 
3807     // Decode the shift amount if not RRX.
3808     uint32_t amt =
3809         (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3810 
3811     uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3812     if (!success)
3813       return false;
3814 
3815     // The context specifies that an immediate is to be moved into Rd.
3816     EmulateInstruction::Context context;
3817     context.type = EmulateInstruction::eContextImmediate;
3818     context.SetNoArgs();
3819 
3820     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3821       return false;
3822   }
3823   return true;
3824 }
3825 
3826 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3827                                             const ARMEncoding encoding,
3828                                             ARM_ShifterType shift_type) {
3829   // assert(shift_type == SRType_ASR
3830   //        || shift_type == SRType_LSL
3831   //        || shift_type == SRType_LSR
3832   //        || shift_type == SRType_ROR);
3833 
3834   bool success = false;
3835 
3836   if (ConditionPassed(opcode)) {
3837     uint32_t Rd; // the destination register
3838     uint32_t Rn; // the first operand register
3839     uint32_t
3840         Rm; // the register whose bottom byte contains the amount to shift by
3841     uint32_t carry; // the carry bit after the shift operation
3842     bool setflags;
3843     switch (encoding) {
3844     case eEncodingT1:
3845       Rd = Bits32(opcode, 2, 0);
3846       Rn = Rd;
3847       Rm = Bits32(opcode, 5, 3);
3848       setflags = !InITBlock();
3849       break;
3850     case eEncodingT2:
3851       Rd = Bits32(opcode, 11, 8);
3852       Rn = Bits32(opcode, 19, 16);
3853       Rm = Bits32(opcode, 3, 0);
3854       setflags = BitIsSet(opcode, 20);
3855       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3856         return false;
3857       break;
3858     case eEncodingA1:
3859       Rd = Bits32(opcode, 15, 12);
3860       Rn = Bits32(opcode, 3, 0);
3861       Rm = Bits32(opcode, 11, 8);
3862       setflags = BitIsSet(opcode, 20);
3863       if (Rd == 15 || Rn == 15 || Rm == 15)
3864         return false;
3865       break;
3866     default:
3867       return false;
3868     }
3869 
3870     // Get the first operand.
3871     uint32_t value = ReadCoreReg(Rn, &success);
3872     if (!success)
3873       return false;
3874     // Get the Rm register content.
3875     uint32_t val = ReadCoreReg(Rm, &success);
3876     if (!success)
3877       return false;
3878 
3879     // Get the shift amount.
3880     uint32_t amt = Bits32(val, 7, 0);
3881 
3882     uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3883     if (!success)
3884       return false;
3885 
3886     // The context specifies that an immediate is to be moved into Rd.
3887     EmulateInstruction::Context context;
3888     context.type = EmulateInstruction::eContextImmediate;
3889     context.SetNoArgs();
3890 
3891     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3892       return false;
3893   }
3894   return true;
3895 }
3896 
3897 // LDM loads multiple registers from consecutive memory locations, using an
3898 // address from a base register.  Optionally the address just above the highest
3899 // of those locations can be written back to the base register.
3900 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3901                                        const ARMEncoding encoding) {
3902 #if 0
3903     // ARM pseudo code...
3904     if ConditionPassed()
3905         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3906         address = R[n];
3907 
3908         for i = 0 to 14
3909             if registers<i> == '1' then
3910                 R[i] = MemA[address, 4]; address = address + 4;
3911         if registers<15> == '1' then
3912             LoadWritePC (MemA[address, 4]);
3913 
3914         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3915         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3916 
3917 #endif
3918 
3919   bool success = false;
3920   if (ConditionPassed(opcode)) {
3921     uint32_t n;
3922     uint32_t registers = 0;
3923     bool wback;
3924     const uint32_t addr_byte_size = GetAddressByteSize();
3925     switch (encoding) {
3926     case eEncodingT1:
3927       // n = UInt(Rn); registers = '00000000':register_list; wback =
3928       // (registers<n> == '0');
3929       n = Bits32(opcode, 10, 8);
3930       registers = Bits32(opcode, 7, 0);
3931       registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3932       wback = BitIsClear(registers, n);
3933       // if BitCount(registers) < 1 then UNPREDICTABLE;
3934       if (BitCount(registers) < 1)
3935         return false;
3936       break;
3937     case eEncodingT2:
3938       // if W == '1' && Rn == '1101' then SEE POP;
3939       // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3940       n = Bits32(opcode, 19, 16);
3941       registers = Bits32(opcode, 15, 0);
3942       registers = registers & 0xdfff; // Make sure bit 13 is zero.
3943       wback = BitIsSet(opcode, 21);
3944 
3945       // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3946       // UNPREDICTABLE;
3947       if ((n == 15) || (BitCount(registers) < 2) ||
3948           (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3949         return false;
3950 
3951       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3952       // UNPREDICTABLE;
3953       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3954         return false;
3955 
3956       // if wback && registers<n> == '1' then UNPREDICTABLE;
3957       if (wback && BitIsSet(registers, n))
3958         return false;
3959       break;
3960 
3961     case eEncodingA1:
3962       n = Bits32(opcode, 19, 16);
3963       registers = Bits32(opcode, 15, 0);
3964       wback = BitIsSet(opcode, 21);
3965       if ((n == 15) || (BitCount(registers) < 1))
3966         return false;
3967       break;
3968     default:
3969       return false;
3970     }
3971 
3972     int32_t offset = 0;
3973     const addr_t base_address =
3974         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3975     if (!success)
3976       return false;
3977 
3978     EmulateInstruction::Context context;
3979     context.type = EmulateInstruction::eContextRegisterPlusOffset;
3980     std::optional<RegisterInfo> dwarf_reg =
3981         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
3982     context.SetRegisterPlusOffset(*dwarf_reg, offset);
3983 
3984     for (int i = 0; i < 14; ++i) {
3985       if (BitIsSet(registers, i)) {
3986         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3987         context.SetRegisterPlusOffset(*dwarf_reg, offset);
3988         if (wback && (n == 13)) // Pop Instruction
3989         {
3990           context.type = EmulateInstruction::eContextPopRegisterOffStack;
3991           context.SetAddress(base_address + offset);
3992         }
3993 
3994         // R[i] = MemA [address, 4]; address = address + 4;
3995         uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
3996                                  0, &success);
3997         if (!success)
3998           return false;
3999 
4000         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4001                                    data))
4002           return false;
4003 
4004         offset += addr_byte_size;
4005       }
4006     }
4007 
4008     if (BitIsSet(registers, 15)) {
4009       // LoadWritePC (MemA [address, 4]);
4010       context.type = EmulateInstruction::eContextRegisterPlusOffset;
4011       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4012       uint32_t data =
4013           MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4014       if (!success)
4015         return false;
4016       // In ARMv5T and above, this is an interworking branch.
4017       if (!LoadWritePC(context, data))
4018         return false;
4019     }
4020 
4021     if (wback && BitIsClear(registers, n)) {
4022       // R[n] = R[n] + 4 * BitCount (registers)
4023       int32_t offset = addr_byte_size * BitCount(registers);
4024       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4025       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4026 
4027       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4028                                  base_address + offset))
4029         return false;
4030     }
4031     if (wback && BitIsSet(registers, n))
4032       // R[n] bits(32) UNKNOWN;
4033       return WriteBits32Unknown(n);
4034   }
4035   return true;
4036 }
4037 
4038 // LDMDA loads multiple registers from consecutive memory locations using an
4039 // address from a base register.
4040 // The consecutive memory locations end at this address and the address just
4041 // below the lowest of those locations can optionally be written back to the
4042 // base register.
4043 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4044                                          const ARMEncoding encoding) {
4045 #if 0
4046     // ARM pseudo code...
4047     if ConditionPassed() then
4048         EncodingSpecificOperations();
4049         address = R[n] - 4*BitCount(registers) + 4;
4050 
4051         for i = 0 to 14
4052             if registers<i> == '1' then
4053                   R[i] = MemA[address,4]; address = address + 4;
4054 
4055         if registers<15> == '1' then
4056             LoadWritePC(MemA[address,4]);
4057 
4058         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4059         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4060 #endif
4061 
4062   bool success = false;
4063 
4064   if (ConditionPassed(opcode)) {
4065     uint32_t n;
4066     uint32_t registers = 0;
4067     bool wback;
4068     const uint32_t addr_byte_size = GetAddressByteSize();
4069 
4070     // EncodingSpecificOperations();
4071     switch (encoding) {
4072     case eEncodingA1:
4073       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4074       n = Bits32(opcode, 19, 16);
4075       registers = Bits32(opcode, 15, 0);
4076       wback = BitIsSet(opcode, 21);
4077 
4078       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4079       if ((n == 15) || (BitCount(registers) < 1))
4080         return false;
4081 
4082       break;
4083 
4084     default:
4085       return false;
4086     }
4087     // address = R[n] - 4*BitCount(registers) + 4;
4088 
4089     int32_t offset = 0;
4090     addr_t Rn = ReadCoreReg(n, &success);
4091 
4092     if (!success)
4093       return false;
4094 
4095     addr_t address =
4096         Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4097 
4098     EmulateInstruction::Context context;
4099     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4100     std::optional<RegisterInfo> dwarf_reg =
4101         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4102     context.SetRegisterPlusOffset(*dwarf_reg, offset);
4103 
4104     // for i = 0 to 14
4105     for (int i = 0; i < 14; ++i) {
4106       // if registers<i> == '1' then
4107       if (BitIsSet(registers, i)) {
4108         // R[i] = MemA[address,4]; address = address + 4;
4109         context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4110         uint32_t data =
4111             MemARead(context, address + offset, addr_byte_size, 0, &success);
4112         if (!success)
4113           return false;
4114         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4115                                    data))
4116           return false;
4117         offset += addr_byte_size;
4118       }
4119     }
4120 
4121     // if registers<15> == '1' then
4122     //     LoadWritePC(MemA[address,4]);
4123     if (BitIsSet(registers, 15)) {
4124       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4125       uint32_t data =
4126           MemARead(context, address + offset, addr_byte_size, 0, &success);
4127       if (!success)
4128         return false;
4129       // In ARMv5T and above, this is an interworking branch.
4130       if (!LoadWritePC(context, data))
4131         return false;
4132     }
4133 
4134     // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4135     if (wback && BitIsClear(registers, n)) {
4136 
4137       offset = (addr_byte_size * BitCount(registers)) * -1;
4138       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4139       context.SetImmediateSigned(offset);
4140       addr_t addr = Rn + offset;
4141       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4142                                  addr))
4143         return false;
4144     }
4145 
4146     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4147     if (wback && BitIsSet(registers, n))
4148       return WriteBits32Unknown(n);
4149   }
4150   return true;
4151 }
4152 
4153 // LDMDB loads multiple registers from consecutive memory locations using an
4154 // address from a base register.  The
4155 // consecutive memory locations end just below this address, and the address of
4156 // the lowest of those locations can be optionally written back to the base
4157 // register.
4158 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4159                                          const ARMEncoding encoding) {
4160 #if 0
4161     // ARM pseudo code...
4162     if ConditionPassed() then
4163         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4164         address = R[n] - 4*BitCount(registers);
4165 
4166         for i = 0 to 14
4167             if registers<i> == '1' then
4168                   R[i] = MemA[address,4]; address = address + 4;
4169         if registers<15> == '1' then
4170                   LoadWritePC(MemA[address,4]);
4171 
4172         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4173         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4174 #endif
4175 
4176   bool success = false;
4177 
4178   if (ConditionPassed(opcode)) {
4179     uint32_t n;
4180     uint32_t registers = 0;
4181     bool wback;
4182     const uint32_t addr_byte_size = GetAddressByteSize();
4183     switch (encoding) {
4184     case eEncodingT1:
4185       // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4186       n = Bits32(opcode, 19, 16);
4187       registers = Bits32(opcode, 15, 0);
4188       registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4189       wback = BitIsSet(opcode, 21);
4190 
4191       // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4192       // UNPREDICTABLE;
4193       if ((n == 15) || (BitCount(registers) < 2) ||
4194           (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4195         return false;
4196 
4197       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4198       // UNPREDICTABLE;
4199       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4200         return false;
4201 
4202       // if wback && registers<n> == '1' then UNPREDICTABLE;
4203       if (wback && BitIsSet(registers, n))
4204         return false;
4205 
4206       break;
4207 
4208     case eEncodingA1:
4209       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4210       n = Bits32(opcode, 19, 16);
4211       registers = Bits32(opcode, 15, 0);
4212       wback = BitIsSet(opcode, 21);
4213 
4214       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4215       if ((n == 15) || (BitCount(registers) < 1))
4216         return false;
4217 
4218       break;
4219 
4220     default:
4221       return false;
4222     }
4223 
4224     // address = R[n] - 4*BitCount(registers);
4225 
4226     int32_t offset = 0;
4227     addr_t Rn =
4228         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4229 
4230     if (!success)
4231       return false;
4232 
4233     addr_t address = Rn - (addr_byte_size * BitCount(registers));
4234     EmulateInstruction::Context context;
4235     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4236     std::optional<RegisterInfo> dwarf_reg =
4237         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4238     context.SetRegisterPlusOffset(*dwarf_reg, Rn - address);
4239 
4240     for (int i = 0; i < 14; ++i) {
4241       if (BitIsSet(registers, i)) {
4242         // R[i] = MemA[address,4]; address = address + 4;
4243         context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4244         uint32_t data =
4245             MemARead(context, address + offset, addr_byte_size, 0, &success);
4246         if (!success)
4247           return false;
4248 
4249         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4250                                    data))
4251           return false;
4252 
4253         offset += addr_byte_size;
4254       }
4255     }
4256 
4257     // if registers<15> == '1' then
4258     //     LoadWritePC(MemA[address,4]);
4259     if (BitIsSet(registers, 15)) {
4260       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4261       uint32_t data =
4262           MemARead(context, address + offset, addr_byte_size, 0, &success);
4263       if (!success)
4264         return false;
4265       // In ARMv5T and above, this is an interworking branch.
4266       if (!LoadWritePC(context, data))
4267         return false;
4268     }
4269 
4270     // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4271     if (wback && BitIsClear(registers, n)) {
4272 
4273       offset = (addr_byte_size * BitCount(registers)) * -1;
4274       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4275       context.SetImmediateSigned(offset);
4276       addr_t addr = Rn + offset;
4277       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4278                                  addr))
4279         return false;
4280     }
4281 
4282     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4283     // possible for encoding A1
4284     if (wback && BitIsSet(registers, n))
4285       return WriteBits32Unknown(n);
4286   }
4287   return true;
4288 }
4289 
4290 // LDMIB loads multiple registers from consecutive memory locations using an
4291 // address from a base register.  The
4292 // consecutive memory locations start just above this address, and thea ddress
4293 // of the last of those locations can optinoally be written back to the base
4294 // register.
4295 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4296                                          const ARMEncoding encoding) {
4297 #if 0
4298     if ConditionPassed() then
4299         EncodingSpecificOperations();
4300         address = R[n] + 4;
4301 
4302         for i = 0 to 14
4303             if registers<i> == '1' then
4304                   R[i] = MemA[address,4]; address = address + 4;
4305         if registers<15> == '1' then
4306             LoadWritePC(MemA[address,4]);
4307 
4308         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4309         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4310 #endif
4311 
4312   bool success = false;
4313 
4314   if (ConditionPassed(opcode)) {
4315     uint32_t n;
4316     uint32_t registers = 0;
4317     bool wback;
4318     const uint32_t addr_byte_size = GetAddressByteSize();
4319     switch (encoding) {
4320     case eEncodingA1:
4321       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4322       n = Bits32(opcode, 19, 16);
4323       registers = Bits32(opcode, 15, 0);
4324       wback = BitIsSet(opcode, 21);
4325 
4326       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4327       if ((n == 15) || (BitCount(registers) < 1))
4328         return false;
4329 
4330       break;
4331     default:
4332       return false;
4333     }
4334     // address = R[n] + 4;
4335 
4336     int32_t offset = 0;
4337     addr_t Rn =
4338         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4339 
4340     if (!success)
4341       return false;
4342 
4343     addr_t address = Rn + addr_byte_size;
4344 
4345     EmulateInstruction::Context context;
4346     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4347     std::optional<RegisterInfo> dwarf_reg =
4348         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4349     context.SetRegisterPlusOffset(*dwarf_reg, offset);
4350 
4351     for (int i = 0; i < 14; ++i) {
4352       if (BitIsSet(registers, i)) {
4353         // R[i] = MemA[address,4]; address = address + 4;
4354 
4355         context.SetRegisterPlusOffset(*dwarf_reg, offset + addr_byte_size);
4356         uint32_t data =
4357             MemARead(context, address + offset, addr_byte_size, 0, &success);
4358         if (!success)
4359           return false;
4360 
4361         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4362                                    data))
4363           return false;
4364 
4365         offset += addr_byte_size;
4366       }
4367     }
4368 
4369     // if registers<15> == '1' then
4370     //     LoadWritePC(MemA[address,4]);
4371     if (BitIsSet(registers, 15)) {
4372       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4373       uint32_t data =
4374           MemARead(context, address + offset, addr_byte_size, 0, &success);
4375       if (!success)
4376         return false;
4377       // In ARMv5T and above, this is an interworking branch.
4378       if (!LoadWritePC(context, data))
4379         return false;
4380     }
4381 
4382     // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4383     if (wback && BitIsClear(registers, n)) {
4384 
4385       offset = addr_byte_size * BitCount(registers);
4386       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4387       context.SetImmediateSigned(offset);
4388       addr_t addr = Rn + offset;
4389       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4390                                  addr))
4391         return false;
4392     }
4393 
4394     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4395     // possible for encoding A1
4396     if (wback && BitIsSet(registers, n))
4397       return WriteBits32Unknown(n);
4398   }
4399   return true;
4400 }
4401 
4402 // Load Register (immediate) calculates an address from a base register value
4403 // and an immediate offset, loads a word from memory, and writes to a register.
4404 // LDR (immediate, Thumb)
4405 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4406                                               const ARMEncoding encoding) {
4407 #if 0
4408     // ARM pseudo code...
4409     if (ConditionPassed())
4410     {
4411         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4412         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4413         address = if index then offset_addr else R[n];
4414         data = MemU[address,4];
4415         if wback then R[n] = offset_addr;
4416         if t == 15 then
4417             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4418         elsif UnalignedSupport() || address<1:0> = '00' then
4419             R[t] = data;
4420         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4421     }
4422 #endif
4423 
4424   bool success = false;
4425 
4426   if (ConditionPassed(opcode)) {
4427     uint32_t Rt;        // the destination register
4428     uint32_t Rn;        // the base register
4429     uint32_t imm32;     // the immediate offset used to form the address
4430     addr_t offset_addr; // the offset address
4431     addr_t address;     // the calculated address
4432     uint32_t data;      // the literal data value from memory load
4433     bool add, index, wback;
4434     switch (encoding) {
4435     case eEncodingT1:
4436       Rt = Bits32(opcode, 2, 0);
4437       Rn = Bits32(opcode, 5, 3);
4438       imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4439       // index = TRUE; add = TRUE; wback = FALSE
4440       add = true;
4441       index = true;
4442       wback = false;
4443 
4444       break;
4445 
4446     case eEncodingT2:
4447       // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4448       Rt = Bits32(opcode, 10, 8);
4449       Rn = 13;
4450       imm32 = Bits32(opcode, 7, 0) << 2;
4451 
4452       // index = TRUE; add = TRUE; wback = FALSE;
4453       index = true;
4454       add = true;
4455       wback = false;
4456 
4457       break;
4458 
4459     case eEncodingT3:
4460       // if Rn == '1111' then SEE LDR (literal);
4461       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4462       Rt = Bits32(opcode, 15, 12);
4463       Rn = Bits32(opcode, 19, 16);
4464       imm32 = Bits32(opcode, 11, 0);
4465 
4466       // index = TRUE; add = TRUE; wback = FALSE;
4467       index = true;
4468       add = true;
4469       wback = false;
4470 
4471       // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4472       if ((Rt == 15) && InITBlock() && !LastInITBlock())
4473         return false;
4474 
4475       break;
4476 
4477     case eEncodingT4:
4478       // if Rn == '1111' then SEE LDR (literal);
4479       // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4480       // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4481       // '00000100' then SEE POP;
4482       // if P == '0' && W == '0' then UNDEFINED;
4483       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4484         return false;
4485 
4486       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4487       Rt = Bits32(opcode, 15, 12);
4488       Rn = Bits32(opcode, 19, 16);
4489       imm32 = Bits32(opcode, 7, 0);
4490 
4491       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4492       index = BitIsSet(opcode, 10);
4493       add = BitIsSet(opcode, 9);
4494       wback = BitIsSet(opcode, 8);
4495 
4496       // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4497       // then UNPREDICTABLE;
4498       if ((wback && (Rn == Rt)) ||
4499           ((Rt == 15) && InITBlock() && !LastInITBlock()))
4500         return false;
4501 
4502       break;
4503 
4504     default:
4505       return false;
4506     }
4507     uint32_t base = ReadCoreReg(Rn, &success);
4508     if (!success)
4509       return false;
4510     if (add)
4511       offset_addr = base + imm32;
4512     else
4513       offset_addr = base - imm32;
4514 
4515     address = (index ? offset_addr : base);
4516 
4517     std::optional<RegisterInfo> base_reg =
4518         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn);
4519     if (wback) {
4520       EmulateInstruction::Context ctx;
4521       if (Rn == 13) {
4522         ctx.type = eContextAdjustStackPointer;
4523         ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4524       } else if (Rn == GetFramePointerRegisterNumber()) {
4525         ctx.type = eContextSetFramePointer;
4526         ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4527       } else {
4528         ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4529         ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4530       }
4531 
4532       if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4533                                  offset_addr))
4534         return false;
4535     }
4536 
4537     // Prepare to write to the Rt register.
4538     EmulateInstruction::Context context;
4539     context.type = EmulateInstruction::eContextRegisterLoad;
4540     context.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4541 
4542     // Read memory from the address.
4543     data = MemURead(context, address, 4, 0, &success);
4544     if (!success)
4545       return false;
4546 
4547     if (Rt == 15) {
4548       if (Bits32(address, 1, 0) == 0) {
4549         if (!LoadWritePC(context, data))
4550           return false;
4551       } else
4552         return false;
4553     } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4554       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4555                                  data))
4556         return false;
4557     } else
4558       WriteBits32Unknown(Rt);
4559   }
4560   return true;
4561 }
4562 
4563 // STM (Store Multiple Increment After) stores multiple registers to consecutive
4564 // memory locations using an address
4565 // from a base register.  The consecutive memory locations start at this
4566 // address, and the address just above the last of those locations can
4567 // optionally be written back to the base register.
4568 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4569                                        const ARMEncoding encoding) {
4570 #if 0
4571     if ConditionPassed() then
4572         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4573         address = R[n];
4574 
4575         for i = 0 to 14
4576             if registers<i> == '1' then
4577                 if i == n && wback && i != LowestSetBit(registers) then
4578                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4579                 else
4580                     MemA[address,4] = R[i];
4581                 address = address + 4;
4582 
4583         if registers<15> == '1' then // Only possible for encoding A1
4584             MemA[address,4] = PCStoreValue();
4585         if wback then R[n] = R[n] + 4*BitCount(registers);
4586 #endif
4587 
4588   bool success = false;
4589 
4590   if (ConditionPassed(opcode)) {
4591     uint32_t n;
4592     uint32_t registers = 0;
4593     bool wback;
4594     const uint32_t addr_byte_size = GetAddressByteSize();
4595 
4596     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4597     switch (encoding) {
4598     case eEncodingT1:
4599       // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4600       n = Bits32(opcode, 10, 8);
4601       registers = Bits32(opcode, 7, 0);
4602       registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4603       wback = true;
4604 
4605       // if BitCount(registers) < 1 then UNPREDICTABLE;
4606       if (BitCount(registers) < 1)
4607         return false;
4608 
4609       break;
4610 
4611     case eEncodingT2:
4612       // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4613       n = Bits32(opcode, 19, 16);
4614       registers = Bits32(opcode, 15, 0);
4615       registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4616       wback = BitIsSet(opcode, 21);
4617 
4618       // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4619       if ((n == 15) || (BitCount(registers) < 2))
4620         return false;
4621 
4622       // if wback && registers<n> == '1' then UNPREDICTABLE;
4623       if (wback && BitIsSet(registers, n))
4624         return false;
4625 
4626       break;
4627 
4628     case eEncodingA1:
4629       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4630       n = Bits32(opcode, 19, 16);
4631       registers = Bits32(opcode, 15, 0);
4632       wback = BitIsSet(opcode, 21);
4633 
4634       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4635       if ((n == 15) || (BitCount(registers) < 1))
4636         return false;
4637 
4638       break;
4639 
4640     default:
4641       return false;
4642     }
4643 
4644     // address = R[n];
4645     int32_t offset = 0;
4646     const addr_t address =
4647         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4648     if (!success)
4649       return false;
4650 
4651     EmulateInstruction::Context context;
4652     context.type = EmulateInstruction::eContextRegisterStore;
4653     std::optional<RegisterInfo> base_reg =
4654         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4655 
4656     // for i = 0 to 14
4657     uint32_t lowest_set_bit = 14;
4658     for (uint32_t i = 0; i < 14; ++i) {
4659       // if registers<i> == '1' then
4660       if (BitIsSet(registers, i)) {
4661         if (i < lowest_set_bit)
4662           lowest_set_bit = i;
4663         // if i == n && wback && i != LowestSetBit(registers) then
4664         if ((i == n) && wback && (i != lowest_set_bit))
4665           // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4666           // T1 and A1
4667           WriteBits32UnknownToMemory(address + offset);
4668         else {
4669           // MemA[address,4] = R[i];
4670           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4671                                                0, &success);
4672           if (!success)
4673             return false;
4674 
4675           std::optional<RegisterInfo> data_reg =
4676               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4677           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
4678           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4679             return false;
4680         }
4681 
4682         // address = address + 4;
4683         offset += addr_byte_size;
4684       }
4685     }
4686 
4687     // if registers<15> == '1' then // Only possible for encoding A1
4688     //     MemA[address,4] = PCStoreValue();
4689     if (BitIsSet(registers, 15)) {
4690       std::optional<RegisterInfo> pc_reg =
4691           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4692       context.SetRegisterPlusOffset(*pc_reg, 8);
4693       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4694       if (!success)
4695         return false;
4696 
4697       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4698         return false;
4699     }
4700 
4701     // if wback then R[n] = R[n] + 4*BitCount(registers);
4702     if (wback) {
4703       offset = addr_byte_size * BitCount(registers);
4704       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4705       context.SetImmediateSigned(offset);
4706       addr_t data = address + offset;
4707       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4708                                  data))
4709         return false;
4710     }
4711   }
4712   return true;
4713 }
4714 
4715 // STMDA (Store Multiple Decrement After) stores multiple registers to
4716 // consecutive memory locations using an address from a base register.  The
4717 // consecutive memory locations end at this address, and the address just below
4718 // the lowest of those locations can optionally be written back to the base
4719 // register.
4720 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4721                                          const ARMEncoding encoding) {
4722 #if 0
4723     if ConditionPassed() then
4724         EncodingSpecificOperations();
4725         address = R[n] - 4*BitCount(registers) + 4;
4726 
4727         for i = 0 to 14
4728             if registers<i> == '1' then
4729                 if i == n && wback && i != LowestSetBit(registers) then
4730                     MemA[address,4] = bits(32) UNKNOWN;
4731                 else
4732                     MemA[address,4] = R[i];
4733                 address = address + 4;
4734 
4735         if registers<15> == '1' then
4736             MemA[address,4] = PCStoreValue();
4737 
4738         if wback then R[n] = R[n] - 4*BitCount(registers);
4739 #endif
4740 
4741   bool success = false;
4742 
4743   if (ConditionPassed(opcode)) {
4744     uint32_t n;
4745     uint32_t registers = 0;
4746     bool wback;
4747     const uint32_t addr_byte_size = GetAddressByteSize();
4748 
4749     // EncodingSpecificOperations();
4750     switch (encoding) {
4751     case eEncodingA1:
4752       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4753       n = Bits32(opcode, 19, 16);
4754       registers = Bits32(opcode, 15, 0);
4755       wback = BitIsSet(opcode, 21);
4756 
4757       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4758       if ((n == 15) || (BitCount(registers) < 1))
4759         return false;
4760       break;
4761     default:
4762       return false;
4763     }
4764 
4765     // address = R[n] - 4*BitCount(registers) + 4;
4766     int32_t offset = 0;
4767     addr_t Rn = ReadCoreReg(n, &success);
4768     if (!success)
4769       return false;
4770 
4771     addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4772 
4773     EmulateInstruction::Context context;
4774     context.type = EmulateInstruction::eContextRegisterStore;
4775     std::optional<RegisterInfo> base_reg =
4776         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4777 
4778     // for i = 0 to 14
4779     uint32_t lowest_bit_set = 14;
4780     for (uint32_t i = 0; i < 14; ++i) {
4781       // if registers<i> == '1' then
4782       if (BitIsSet(registers, i)) {
4783         if (i < lowest_bit_set)
4784           lowest_bit_set = i;
4785         // if i == n && wback && i != LowestSetBit(registers) then
4786         if ((i == n) && wback && (i != lowest_bit_set))
4787           // MemA[address,4] = bits(32) UNKNOWN;
4788           WriteBits32UnknownToMemory(address + offset);
4789         else {
4790           // MemA[address,4] = R[i];
4791           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4792                                                0, &success);
4793           if (!success)
4794             return false;
4795 
4796           std::optional<RegisterInfo> data_reg =
4797               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4798           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4799                                                   Rn - (address + offset));
4800           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4801             return false;
4802         }
4803 
4804         // address = address + 4;
4805         offset += addr_byte_size;
4806       }
4807     }
4808 
4809     // if registers<15> == '1' then
4810     //    MemA[address,4] = PCStoreValue();
4811     if (BitIsSet(registers, 15)) {
4812       std::optional<RegisterInfo> pc_reg =
4813           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4814       context.SetRegisterPlusOffset(*pc_reg, 8);
4815       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4816       if (!success)
4817         return false;
4818 
4819       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4820         return false;
4821     }
4822 
4823     // if wback then R[n] = R[n] - 4*BitCount(registers);
4824     if (wback) {
4825       offset = (addr_byte_size * BitCount(registers)) * -1;
4826       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4827       context.SetImmediateSigned(offset);
4828       addr_t data = Rn + offset;
4829       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4830                                  data))
4831         return false;
4832     }
4833   }
4834   return true;
4835 }
4836 
4837 // STMDB (Store Multiple Decrement Before) stores multiple registers to
4838 // consecutive memory locations using an address from a base register.  The
4839 // consecutive memory locations end just below this address, and the address of
4840 // the first of those locations can optionally be written back to the base
4841 // register.
4842 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4843                                          const ARMEncoding encoding) {
4844 #if 0
4845     if ConditionPassed() then
4846         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4847         address = R[n] - 4*BitCount(registers);
4848 
4849         for i = 0 to 14
4850             if registers<i> == '1' then
4851                 if i == n && wback && i != LowestSetBit(registers) then
4852                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4853                 else
4854                     MemA[address,4] = R[i];
4855                 address = address + 4;
4856 
4857         if registers<15> == '1' then // Only possible for encoding A1
4858             MemA[address,4] = PCStoreValue();
4859 
4860         if wback then R[n] = R[n] - 4*BitCount(registers);
4861 #endif
4862 
4863   bool success = false;
4864 
4865   if (ConditionPassed(opcode)) {
4866     uint32_t n;
4867     uint32_t registers = 0;
4868     bool wback;
4869     const uint32_t addr_byte_size = GetAddressByteSize();
4870 
4871     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4872     switch (encoding) {
4873     case eEncodingT1:
4874       // if W == '1' && Rn == '1101' then SEE PUSH;
4875       if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4876         // See PUSH
4877       }
4878       // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4879       n = Bits32(opcode, 19, 16);
4880       registers = Bits32(opcode, 15, 0);
4881       registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4882       wback = BitIsSet(opcode, 21);
4883       // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4884       if ((n == 15) || BitCount(registers) < 2)
4885         return false;
4886       // if wback && registers<n> == '1' then UNPREDICTABLE;
4887       if (wback && BitIsSet(registers, n))
4888         return false;
4889       break;
4890 
4891     case eEncodingA1:
4892       // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4893       // PUSH;
4894       if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4895           BitCount(Bits32(opcode, 15, 0)) >= 2) {
4896         // See Push
4897       }
4898       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4899       n = Bits32(opcode, 19, 16);
4900       registers = Bits32(opcode, 15, 0);
4901       wback = BitIsSet(opcode, 21);
4902       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4903       if ((n == 15) || BitCount(registers) < 1)
4904         return false;
4905       break;
4906 
4907     default:
4908       return false;
4909     }
4910 
4911     // address = R[n] - 4*BitCount(registers);
4912 
4913     int32_t offset = 0;
4914     addr_t Rn =
4915         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4916     if (!success)
4917       return false;
4918 
4919     addr_t address = Rn - (addr_byte_size * BitCount(registers));
4920 
4921     EmulateInstruction::Context context;
4922     context.type = EmulateInstruction::eContextRegisterStore;
4923     std::optional<RegisterInfo> base_reg =
4924         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4925 
4926     // for i = 0 to 14
4927     uint32_t lowest_set_bit = 14;
4928     for (uint32_t i = 0; i < 14; ++i) {
4929       // if registers<i> == '1' then
4930       if (BitIsSet(registers, i)) {
4931         if (i < lowest_set_bit)
4932           lowest_set_bit = i;
4933         // if i == n && wback && i != LowestSetBit(registers) then
4934         if ((i == n) && wback && (i != lowest_set_bit))
4935           // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4936           // A1
4937           WriteBits32UnknownToMemory(address + offset);
4938         else {
4939           // MemA[address,4] = R[i];
4940           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4941                                                0, &success);
4942           if (!success)
4943             return false;
4944 
4945           std::optional<RegisterInfo> data_reg =
4946               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4947           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4948                                                   Rn - (address + offset));
4949           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4950             return false;
4951         }
4952 
4953         // address = address + 4;
4954         offset += addr_byte_size;
4955       }
4956     }
4957 
4958     // if registers<15> == '1' then // Only possible for encoding A1
4959     //     MemA[address,4] = PCStoreValue();
4960     if (BitIsSet(registers, 15)) {
4961       std::optional<RegisterInfo> pc_reg =
4962           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4963       context.SetRegisterPlusOffset(*pc_reg, 8);
4964       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4965       if (!success)
4966         return false;
4967 
4968       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4969         return false;
4970     }
4971 
4972     // if wback then R[n] = R[n] - 4*BitCount(registers);
4973     if (wback) {
4974       offset = (addr_byte_size * BitCount(registers)) * -1;
4975       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4976       context.SetImmediateSigned(offset);
4977       addr_t data = Rn + offset;
4978       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4979                                  data))
4980         return false;
4981     }
4982   }
4983   return true;
4984 }
4985 
4986 // STMIB (Store Multiple Increment Before) stores multiple registers to
4987 // consecutive memory locations using an address from a base register.  The
4988 // consecutive memory locations start just above this address, and the address
4989 // of the last of those locations can optionally be written back to the base
4990 // register.
4991 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
4992                                          const ARMEncoding encoding) {
4993 #if 0
4994     if ConditionPassed() then
4995         EncodingSpecificOperations();
4996         address = R[n] + 4;
4997 
4998         for i = 0 to 14
4999             if registers<i> == '1' then
5000                 if i == n && wback && i != LowestSetBit(registers) then
5001                     MemA[address,4] = bits(32) UNKNOWN;
5002                 else
5003                     MemA[address,4] = R[i];
5004                 address = address + 4;
5005 
5006         if registers<15> == '1' then
5007             MemA[address,4] = PCStoreValue();
5008 
5009         if wback then R[n] = R[n] + 4*BitCount(registers);
5010 #endif
5011 
5012   bool success = false;
5013 
5014   if (ConditionPassed(opcode)) {
5015     uint32_t n;
5016     uint32_t registers = 0;
5017     bool wback;
5018     const uint32_t addr_byte_size = GetAddressByteSize();
5019 
5020     // EncodingSpecificOperations();
5021     switch (encoding) {
5022     case eEncodingA1:
5023       // n = UInt(Rn); registers = register_list; wback = (W == '1');
5024       n = Bits32(opcode, 19, 16);
5025       registers = Bits32(opcode, 15, 0);
5026       wback = BitIsSet(opcode, 21);
5027 
5028       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5029       if ((n == 15) && (BitCount(registers) < 1))
5030         return false;
5031       break;
5032     default:
5033       return false;
5034     }
5035     // address = R[n] + 4;
5036 
5037     int32_t offset = 0;
5038     addr_t Rn = ReadCoreReg(n, &success);
5039     if (!success)
5040       return false;
5041 
5042     addr_t address = Rn + addr_byte_size;
5043 
5044     EmulateInstruction::Context context;
5045     context.type = EmulateInstruction::eContextRegisterStore;
5046     std::optional<RegisterInfo> base_reg =
5047         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5048 
5049     uint32_t lowest_set_bit = 14;
5050     // for i = 0 to 14
5051     for (uint32_t i = 0; i < 14; ++i) {
5052       // if registers<i> == '1' then
5053       if (BitIsSet(registers, i)) {
5054         if (i < lowest_set_bit)
5055           lowest_set_bit = i;
5056         // if i == n && wback && i != LowestSetBit(registers) then
5057         if ((i == n) && wback && (i != lowest_set_bit))
5058           // MemA[address,4] = bits(32) UNKNOWN;
5059           WriteBits32UnknownToMemory(address + offset);
5060         // else
5061         else {
5062           // MemA[address,4] = R[i];
5063           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5064                                                0, &success);
5065           if (!success)
5066             return false;
5067 
5068           std::optional<RegisterInfo> data_reg =
5069               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
5070           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5071                                                   offset + addr_byte_size);
5072           if (!MemAWrite(context, address + offset, data, addr_byte_size))
5073             return false;
5074         }
5075 
5076         // address = address + 4;
5077         offset += addr_byte_size;
5078       }
5079     }
5080 
5081     // if registers<15> == '1' then
5082     // MemA[address,4] = PCStoreValue();
5083     if (BitIsSet(registers, 15)) {
5084       std::optional<RegisterInfo> pc_reg =
5085           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
5086       context.SetRegisterPlusOffset(*pc_reg, 8);
5087       const uint32_t pc = ReadCoreReg(PC_REG, &success);
5088       if (!success)
5089         return false;
5090 
5091       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5092         return false;
5093     }
5094 
5095     // if wback then R[n] = R[n] + 4*BitCount(registers);
5096     if (wback) {
5097       offset = addr_byte_size * BitCount(registers);
5098       context.type = EmulateInstruction::eContextAdjustBaseRegister;
5099       context.SetImmediateSigned(offset);
5100       addr_t data = Rn + offset;
5101       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5102                                  data))
5103         return false;
5104     }
5105   }
5106   return true;
5107 }
5108 
5109 // STR (store immediate) calculates an address from a base register value and an
5110 // immediate offset, and stores a word
5111 // from a register to memory.  It can use offset, post-indexed, or pre-indexed
5112 // addressing.
5113 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5114                                             const ARMEncoding encoding) {
5115 #if 0
5116     if ConditionPassed() then
5117         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5118         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5119         address = if index then offset_addr else R[n];
5120         if UnalignedSupport() || address<1:0> == '00' then
5121             MemU[address,4] = R[t];
5122         else // Can only occur before ARMv7
5123             MemU[address,4] = bits(32) UNKNOWN;
5124         if wback then R[n] = offset_addr;
5125 #endif
5126 
5127   bool success = false;
5128 
5129   if (ConditionPassed(opcode)) {
5130     const uint32_t addr_byte_size = GetAddressByteSize();
5131 
5132     uint32_t t;
5133     uint32_t n;
5134     uint32_t imm32;
5135     bool index;
5136     bool add;
5137     bool wback;
5138     // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5139     switch (encoding) {
5140     case eEncodingT1:
5141       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5142       t = Bits32(opcode, 2, 0);
5143       n = Bits32(opcode, 5, 3);
5144       imm32 = Bits32(opcode, 10, 6) << 2;
5145 
5146       // index = TRUE; add = TRUE; wback = FALSE;
5147       index = true;
5148       add = false;
5149       wback = false;
5150       break;
5151 
5152     case eEncodingT2:
5153       // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5154       t = Bits32(opcode, 10, 8);
5155       n = 13;
5156       imm32 = Bits32(opcode, 7, 0) << 2;
5157 
5158       // index = TRUE; add = TRUE; wback = FALSE;
5159       index = true;
5160       add = true;
5161       wback = false;
5162       break;
5163 
5164     case eEncodingT3:
5165       // if Rn == '1111' then UNDEFINED;
5166       if (Bits32(opcode, 19, 16) == 15)
5167         return false;
5168 
5169       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5170       t = Bits32(opcode, 15, 12);
5171       n = Bits32(opcode, 19, 16);
5172       imm32 = Bits32(opcode, 11, 0);
5173 
5174       // index = TRUE; add = TRUE; wback = FALSE;
5175       index = true;
5176       add = true;
5177       wback = false;
5178 
5179       // if t == 15 then UNPREDICTABLE;
5180       if (t == 15)
5181         return false;
5182       break;
5183 
5184     case eEncodingT4:
5185       // if P == '1' && U == '1' && W == '0' then SEE STRT;
5186       // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5187       // '00000100' then SEE PUSH;
5188       // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5189       if ((Bits32(opcode, 19, 16) == 15) ||
5190           (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5191         return false;
5192 
5193       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5194       t = Bits32(opcode, 15, 12);
5195       n = Bits32(opcode, 19, 16);
5196       imm32 = Bits32(opcode, 7, 0);
5197 
5198       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5199       index = BitIsSet(opcode, 10);
5200       add = BitIsSet(opcode, 9);
5201       wback = BitIsSet(opcode, 8);
5202 
5203       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5204       if ((t == 15) || (wback && (n == t)))
5205         return false;
5206       break;
5207 
5208     default:
5209       return false;
5210     }
5211 
5212     addr_t offset_addr;
5213     addr_t address;
5214 
5215     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5216     uint32_t base_address = ReadCoreReg(n, &success);
5217     if (!success)
5218       return false;
5219 
5220     if (add)
5221       offset_addr = base_address + imm32;
5222     else
5223       offset_addr = base_address - imm32;
5224 
5225     // address = if index then offset_addr else R[n];
5226     if (index)
5227       address = offset_addr;
5228     else
5229       address = base_address;
5230 
5231     EmulateInstruction::Context context;
5232     if (n == 13)
5233       context.type = eContextPushRegisterOnStack;
5234     else
5235       context.type = eContextRegisterStore;
5236 
5237     std::optional<RegisterInfo> base_reg =
5238         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5239 
5240     // if UnalignedSupport() || address<1:0> == '00' then
5241     if (UnalignedSupport() ||
5242         (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5243       // MemU[address,4] = R[t];
5244       uint32_t data =
5245           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5246       if (!success)
5247         return false;
5248 
5249       std::optional<RegisterInfo> data_reg =
5250           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5251       int32_t offset = address - base_address;
5252       context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
5253       if (!MemUWrite(context, address, data, addr_byte_size))
5254         return false;
5255     } else {
5256       // MemU[address,4] = bits(32) UNKNOWN;
5257       WriteBits32UnknownToMemory(address);
5258     }
5259 
5260     // if wback then R[n] = offset_addr;
5261     if (wback) {
5262       if (n == 13)
5263         context.type = eContextAdjustStackPointer;
5264       else
5265         context.type = eContextAdjustBaseRegister;
5266       context.SetAddress(offset_addr);
5267 
5268       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5269                                  offset_addr))
5270         return false;
5271     }
5272   }
5273   return true;
5274 }
5275 
5276 // STR (Store Register) calculates an address from a base register value and an
5277 // offset register value, stores a
5278 // word from a register to memory.   The offset register value can optionally
5279 // be shifted.
5280 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5281                                                const ARMEncoding encoding) {
5282 #if 0
5283     if ConditionPassed() then
5284         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5285         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5286         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5287         address = if index then offset_addr else R[n];
5288         if t == 15 then // Only possible for encoding A1
5289             data = PCStoreValue();
5290         else
5291             data = R[t];
5292         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5293             MemU[address,4] = data;
5294         else // Can only occur before ARMv7
5295             MemU[address,4] = bits(32) UNKNOWN;
5296         if wback then R[n] = offset_addr;
5297 #endif
5298 
5299   bool success = false;
5300 
5301   if (ConditionPassed(opcode)) {
5302     const uint32_t addr_byte_size = GetAddressByteSize();
5303 
5304     uint32_t t;
5305     uint32_t n;
5306     uint32_t m;
5307     ARM_ShifterType shift_t;
5308     uint32_t shift_n;
5309     bool index;
5310     bool add;
5311     bool wback;
5312 
5313     // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5314     switch (encoding) {
5315     case eEncodingT1:
5316       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5317       // in ThumbEE";
5318       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5319       t = Bits32(opcode, 2, 0);
5320       n = Bits32(opcode, 5, 3);
5321       m = Bits32(opcode, 8, 6);
5322 
5323       // index = TRUE; add = TRUE; wback = FALSE;
5324       index = true;
5325       add = true;
5326       wback = false;
5327 
5328       // (shift_t, shift_n) = (SRType_LSL, 0);
5329       shift_t = SRType_LSL;
5330       shift_n = 0;
5331       break;
5332 
5333     case eEncodingT2:
5334       // if Rn == '1111' then UNDEFINED;
5335       if (Bits32(opcode, 19, 16) == 15)
5336         return false;
5337 
5338       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5339       t = Bits32(opcode, 15, 12);
5340       n = Bits32(opcode, 19, 16);
5341       m = Bits32(opcode, 3, 0);
5342 
5343       // index = TRUE; add = TRUE; wback = FALSE;
5344       index = true;
5345       add = true;
5346       wback = false;
5347 
5348       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5349       shift_t = SRType_LSL;
5350       shift_n = Bits32(opcode, 5, 4);
5351 
5352       // if t == 15 || BadReg(m) then UNPREDICTABLE;
5353       if ((t == 15) || (BadReg(m)))
5354         return false;
5355       break;
5356 
5357     case eEncodingA1: {
5358       // if P == '0' && W == '1' then SEE STRT;
5359       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5360       t = Bits32(opcode, 15, 12);
5361       n = Bits32(opcode, 19, 16);
5362       m = Bits32(opcode, 3, 0);
5363 
5364       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5365       // (W == '1');
5366       index = BitIsSet(opcode, 24);
5367       add = BitIsSet(opcode, 23);
5368       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5369 
5370       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5371       uint32_t typ = Bits32(opcode, 6, 5);
5372       uint32_t imm5 = Bits32(opcode, 11, 7);
5373       shift_n = DecodeImmShift(typ, imm5, shift_t);
5374 
5375       // if m == 15 then UNPREDICTABLE;
5376       if (m == 15)
5377         return false;
5378 
5379       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5380       if (wback && ((n == 15) || (n == t)))
5381         return false;
5382 
5383       break;
5384     }
5385     default:
5386       return false;
5387     }
5388 
5389     addr_t offset_addr;
5390     addr_t address;
5391     int32_t offset = 0;
5392 
5393     addr_t base_address =
5394         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5395     if (!success)
5396       return false;
5397 
5398     uint32_t Rm_data =
5399         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5400     if (!success)
5401       return false;
5402 
5403     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5404     offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5405     if (!success)
5406       return false;
5407 
5408     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5409     if (add)
5410       offset_addr = base_address + offset;
5411     else
5412       offset_addr = base_address - offset;
5413 
5414     // address = if index then offset_addr else R[n];
5415     if (index)
5416       address = offset_addr;
5417     else
5418       address = base_address;
5419 
5420     uint32_t data;
5421     // if t == 15 then // Only possible for encoding A1
5422     if (t == 15)
5423       // data = PCStoreValue();
5424       data = ReadCoreReg(PC_REG, &success);
5425     else
5426       // data = R[t];
5427       data =
5428           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5429 
5430     if (!success)
5431       return false;
5432 
5433     EmulateInstruction::Context context;
5434     context.type = eContextRegisterStore;
5435 
5436     // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5437     // InstrSet_ARM then
5438     if (UnalignedSupport() ||
5439         (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5440         CurrentInstrSet() == eModeARM) {
5441       // MemU[address,4] = data;
5442 
5443       std::optional<RegisterInfo> base_reg =
5444           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5445       std::optional<RegisterInfo> data_reg =
5446           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5447 
5448       context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5449                                               address - base_address);
5450       if (!MemUWrite(context, address, data, addr_byte_size))
5451         return false;
5452 
5453     } else
5454       // MemU[address,4] = bits(32) UNKNOWN;
5455       WriteBits32UnknownToMemory(address);
5456 
5457     // if wback then R[n] = offset_addr;
5458     if (wback) {
5459       context.type = eContextRegisterLoad;
5460       context.SetAddress(offset_addr);
5461       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5462                                  offset_addr))
5463         return false;
5464     }
5465   }
5466   return true;
5467 }
5468 
5469 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5470                                              const ARMEncoding encoding) {
5471 #if 0
5472     if ConditionPassed() then
5473         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5474         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5475         address = if index then offset_addr else R[n];
5476         MemU[address,1] = R[t]<7:0>;
5477         if wback then R[n] = offset_addr;
5478 #endif
5479 
5480   bool success = false;
5481 
5482   if (ConditionPassed(opcode)) {
5483     uint32_t t;
5484     uint32_t n;
5485     uint32_t imm32;
5486     bool index;
5487     bool add;
5488     bool wback;
5489     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5490     switch (encoding) {
5491     case eEncodingT1:
5492       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5493       t = Bits32(opcode, 2, 0);
5494       n = Bits32(opcode, 5, 3);
5495       imm32 = Bits32(opcode, 10, 6);
5496 
5497       // index = TRUE; add = TRUE; wback = FALSE;
5498       index = true;
5499       add = true;
5500       wback = false;
5501       break;
5502 
5503     case eEncodingT2:
5504       // if Rn == '1111' then UNDEFINED;
5505       if (Bits32(opcode, 19, 16) == 15)
5506         return false;
5507 
5508       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5509       t = Bits32(opcode, 15, 12);
5510       n = Bits32(opcode, 19, 16);
5511       imm32 = Bits32(opcode, 11, 0);
5512 
5513       // index = TRUE; add = TRUE; wback = FALSE;
5514       index = true;
5515       add = true;
5516       wback = false;
5517 
5518       // if BadReg(t) then UNPREDICTABLE;
5519       if (BadReg(t))
5520         return false;
5521       break;
5522 
5523     case eEncodingT3:
5524       // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5525       // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5526       if (Bits32(opcode, 19, 16) == 15)
5527         return false;
5528 
5529       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5530       t = Bits32(opcode, 15, 12);
5531       n = Bits32(opcode, 19, 16);
5532       imm32 = Bits32(opcode, 7, 0);
5533 
5534       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5535       index = BitIsSet(opcode, 10);
5536       add = BitIsSet(opcode, 9);
5537       wback = BitIsSet(opcode, 8);
5538 
5539       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5540       if ((BadReg(t)) || (wback && (n == t)))
5541         return false;
5542       break;
5543 
5544     default:
5545       return false;
5546     }
5547 
5548     addr_t offset_addr;
5549     addr_t address;
5550     addr_t base_address =
5551         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5552     if (!success)
5553       return false;
5554 
5555     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5556     if (add)
5557       offset_addr = base_address + imm32;
5558     else
5559       offset_addr = base_address - imm32;
5560 
5561     // address = if index then offset_addr else R[n];
5562     if (index)
5563       address = offset_addr;
5564     else
5565       address = base_address;
5566 
5567     // MemU[address,1] = R[t]<7:0>
5568     std::optional<RegisterInfo> base_reg =
5569         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5570     std::optional<RegisterInfo> data_reg =
5571         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5572 
5573     EmulateInstruction::Context context;
5574     context.type = eContextRegisterStore;
5575     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5576                                             address - base_address);
5577 
5578     uint32_t data =
5579         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5580     if (!success)
5581       return false;
5582 
5583     data = Bits32(data, 7, 0);
5584 
5585     if (!MemUWrite(context, address, data, 1))
5586       return false;
5587 
5588     // if wback then R[n] = offset_addr;
5589     if (wback) {
5590       context.type = eContextRegisterLoad;
5591       context.SetAddress(offset_addr);
5592       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5593                                  offset_addr))
5594         return false;
5595     }
5596   }
5597 
5598   return true;
5599 }
5600 
5601 // STRH (register) calculates an address from a base register value and an
5602 // offset register value, and stores a
5603 // halfword from a register to memory.  The offset register value can be
5604 // shifted left by 0, 1, 2, or 3 bits.
5605 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5606                                                 const ARMEncoding encoding) {
5607 #if 0
5608     if ConditionPassed() then
5609         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5610         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5611         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5612         address = if index then offset_addr else R[n];
5613         if UnalignedSupport() || address<0> == '0' then
5614             MemU[address,2] = R[t]<15:0>;
5615         else // Can only occur before ARMv7
5616             MemU[address,2] = bits(16) UNKNOWN;
5617         if wback then R[n] = offset_addr;
5618 #endif
5619 
5620   bool success = false;
5621 
5622   if (ConditionPassed(opcode)) {
5623     uint32_t t;
5624     uint32_t n;
5625     uint32_t m;
5626     bool index;
5627     bool add;
5628     bool wback;
5629     ARM_ShifterType shift_t;
5630     uint32_t shift_n;
5631 
5632     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5633     switch (encoding) {
5634     case eEncodingT1:
5635       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5636       // in ThumbEE";
5637       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5638       t = Bits32(opcode, 2, 0);
5639       n = Bits32(opcode, 5, 3);
5640       m = Bits32(opcode, 8, 6);
5641 
5642       // index = TRUE; add = TRUE; wback = FALSE;
5643       index = true;
5644       add = true;
5645       wback = false;
5646 
5647       // (shift_t, shift_n) = (SRType_LSL, 0);
5648       shift_t = SRType_LSL;
5649       shift_n = 0;
5650 
5651       break;
5652 
5653     case eEncodingT2:
5654       // if Rn == '1111' then UNDEFINED;
5655       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5656       t = Bits32(opcode, 15, 12);
5657       n = Bits32(opcode, 19, 16);
5658       m = Bits32(opcode, 3, 0);
5659       if (n == 15)
5660         return false;
5661 
5662       // index = TRUE; add = TRUE; wback = FALSE;
5663       index = true;
5664       add = true;
5665       wback = false;
5666 
5667       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5668       shift_t = SRType_LSL;
5669       shift_n = Bits32(opcode, 5, 4);
5670 
5671       // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5672       if (BadReg(t) || BadReg(m))
5673         return false;
5674 
5675       break;
5676 
5677     case eEncodingA1:
5678       // if P == '0' && W == '1' then SEE STRHT;
5679       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5680       t = Bits32(opcode, 15, 12);
5681       n = Bits32(opcode, 19, 16);
5682       m = Bits32(opcode, 3, 0);
5683 
5684       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5685       // (W == '1');
5686       index = BitIsSet(opcode, 24);
5687       add = BitIsSet(opcode, 23);
5688       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5689 
5690       // (shift_t, shift_n) = (SRType_LSL, 0);
5691       shift_t = SRType_LSL;
5692       shift_n = 0;
5693 
5694       // if t == 15 || m == 15 then UNPREDICTABLE;
5695       if ((t == 15) || (m == 15))
5696         return false;
5697 
5698       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5699       if (wback && ((n == 15) || (n == t)))
5700         return false;
5701 
5702       break;
5703 
5704     default:
5705       return false;
5706     }
5707 
5708     uint32_t Rm = ReadCoreReg(m, &success);
5709     if (!success)
5710       return false;
5711 
5712     uint32_t Rn = ReadCoreReg(n, &success);
5713     if (!success)
5714       return false;
5715 
5716     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5717     uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5718     if (!success)
5719       return false;
5720 
5721     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5722     addr_t offset_addr;
5723     if (add)
5724       offset_addr = Rn + offset;
5725     else
5726       offset_addr = Rn - offset;
5727 
5728     // address = if index then offset_addr else R[n];
5729     addr_t address;
5730     if (index)
5731       address = offset_addr;
5732     else
5733       address = Rn;
5734 
5735     EmulateInstruction::Context context;
5736     context.type = eContextRegisterStore;
5737 
5738     // if UnalignedSupport() || address<0> == '0' then
5739     if (UnalignedSupport() || BitIsClear(address, 0)) {
5740       // MemU[address,2] = R[t]<15:0>;
5741       uint32_t Rt = ReadCoreReg(t, &success);
5742       if (!success)
5743         return false;
5744 
5745       EmulateInstruction::Context context;
5746       context.type = eContextRegisterStore;
5747       std::optional<RegisterInfo> base_reg =
5748           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5749       std::optional<RegisterInfo> offset_reg =
5750           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
5751       std::optional<RegisterInfo> data_reg =
5752           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5753       context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
5754                                                       *data_reg);
5755 
5756       if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5757         return false;
5758     } else // Can only occur before ARMv7
5759     {
5760       // MemU[address,2] = bits(16) UNKNOWN;
5761     }
5762 
5763     // if wback then R[n] = offset_addr;
5764     if (wback) {
5765       context.type = eContextAdjustBaseRegister;
5766       context.SetAddress(offset_addr);
5767       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5768                                  offset_addr))
5769         return false;
5770     }
5771   }
5772 
5773   return true;
5774 }
5775 
5776 // Add with Carry (immediate) adds an immediate value and the carry flag value
5777 // to a register value, and writes the result to the destination register.  It
5778 // can optionally update the condition flags based on the result.
5779 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5780                                           const ARMEncoding encoding) {
5781 #if 0
5782     // ARM pseudo code...
5783     if ConditionPassed() then
5784         EncodingSpecificOperations();
5785         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5786         if d == 15 then         // Can only occur for ARM encoding
5787             ALUWritePC(result); // setflags is always FALSE here
5788         else
5789             R[d] = result;
5790             if setflags then
5791                 APSR.N = result<31>;
5792                 APSR.Z = IsZeroBit(result);
5793                 APSR.C = carry;
5794                 APSR.V = overflow;
5795 #endif
5796 
5797   bool success = false;
5798 
5799   if (ConditionPassed(opcode)) {
5800     uint32_t Rd, Rn;
5801     uint32_t
5802         imm32; // the immediate value to be added to the value obtained from Rn
5803     bool setflags;
5804     switch (encoding) {
5805     case eEncodingT1:
5806       Rd = Bits32(opcode, 11, 8);
5807       Rn = Bits32(opcode, 19, 16);
5808       setflags = BitIsSet(opcode, 20);
5809       imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5810       if (BadReg(Rd) || BadReg(Rn))
5811         return false;
5812       break;
5813     case eEncodingA1:
5814       Rd = Bits32(opcode, 15, 12);
5815       Rn = Bits32(opcode, 19, 16);
5816       setflags = BitIsSet(opcode, 20);
5817       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5818 
5819       if (Rd == 15 && setflags)
5820         return EmulateSUBSPcLrEtc(opcode, encoding);
5821       break;
5822     default:
5823       return false;
5824     }
5825 
5826     // Read the first operand.
5827     int32_t val1 = ReadCoreReg(Rn, &success);
5828     if (!success)
5829       return false;
5830 
5831     AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5832 
5833     EmulateInstruction::Context context;
5834     context.type = EmulateInstruction::eContextImmediate;
5835     context.SetNoArgs();
5836 
5837     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5838                                    res.carry_out, res.overflow))
5839       return false;
5840   }
5841   return true;
5842 }
5843 
5844 // Add with Carry (register) adds a register value, the carry flag value, and
5845 // an optionally-shifted register value, and writes the result to the
5846 // destination register.  It can optionally update the condition flags based on
5847 // the result.
5848 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5849                                           const ARMEncoding encoding) {
5850 #if 0
5851     // ARM pseudo code...
5852     if ConditionPassed() then
5853         EncodingSpecificOperations();
5854         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5855         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5856         if d == 15 then         // Can only occur for ARM encoding
5857             ALUWritePC(result); // setflags is always FALSE here
5858         else
5859             R[d] = result;
5860             if setflags then
5861                 APSR.N = result<31>;
5862                 APSR.Z = IsZeroBit(result);
5863                 APSR.C = carry;
5864                 APSR.V = overflow;
5865 #endif
5866 
5867   bool success = false;
5868 
5869   if (ConditionPassed(opcode)) {
5870     uint32_t Rd, Rn, Rm;
5871     ARM_ShifterType shift_t;
5872     uint32_t shift_n; // the shift applied to the value read from Rm
5873     bool setflags;
5874     switch (encoding) {
5875     case eEncodingT1:
5876       Rd = Rn = Bits32(opcode, 2, 0);
5877       Rm = Bits32(opcode, 5, 3);
5878       setflags = !InITBlock();
5879       shift_t = SRType_LSL;
5880       shift_n = 0;
5881       break;
5882     case eEncodingT2:
5883       Rd = Bits32(opcode, 11, 8);
5884       Rn = Bits32(opcode, 19, 16);
5885       Rm = Bits32(opcode, 3, 0);
5886       setflags = BitIsSet(opcode, 20);
5887       shift_n = DecodeImmShiftThumb(opcode, shift_t);
5888       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5889         return false;
5890       break;
5891     case eEncodingA1:
5892       Rd = Bits32(opcode, 15, 12);
5893       Rn = Bits32(opcode, 19, 16);
5894       Rm = Bits32(opcode, 3, 0);
5895       setflags = BitIsSet(opcode, 20);
5896       shift_n = DecodeImmShiftARM(opcode, shift_t);
5897 
5898       if (Rd == 15 && setflags)
5899         return EmulateSUBSPcLrEtc(opcode, encoding);
5900       break;
5901     default:
5902       return false;
5903     }
5904 
5905     // Read the first operand.
5906     int32_t val1 = ReadCoreReg(Rn, &success);
5907     if (!success)
5908       return false;
5909 
5910     // Read the second operand.
5911     int32_t val2 = ReadCoreReg(Rm, &success);
5912     if (!success)
5913       return false;
5914 
5915     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5916     if (!success)
5917       return false;
5918     AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5919 
5920     EmulateInstruction::Context context;
5921     context.type = EmulateInstruction::eContextImmediate;
5922     context.SetNoArgs();
5923 
5924     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5925                                    res.carry_out, res.overflow))
5926       return false;
5927   }
5928   return true;
5929 }
5930 
5931 // This instruction adds an immediate value to the PC value to form a PC-
5932 // relative address, and writes the result to the destination register.
5933 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5934                                        const ARMEncoding encoding) {
5935 #if 0
5936     // ARM pseudo code...
5937     if ConditionPassed() then
5938         EncodingSpecificOperations();
5939         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5940         if d == 15 then         // Can only occur for ARM encodings
5941             ALUWritePC(result);
5942         else
5943             R[d] = result;
5944 #endif
5945 
5946   bool success = false;
5947 
5948   if (ConditionPassed(opcode)) {
5949     uint32_t Rd;
5950     uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5951     bool add;
5952     switch (encoding) {
5953     case eEncodingT1:
5954       Rd = Bits32(opcode, 10, 8);
5955       imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5956       add = true;
5957       break;
5958     case eEncodingT2:
5959     case eEncodingT3:
5960       Rd = Bits32(opcode, 11, 8);
5961       imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5962       add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5963       if (BadReg(Rd))
5964         return false;
5965       break;
5966     case eEncodingA1:
5967     case eEncodingA2:
5968       Rd = Bits32(opcode, 15, 12);
5969       imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
5970       add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5971       break;
5972     default:
5973       return false;
5974     }
5975 
5976     // Read the PC value.
5977     uint32_t pc = ReadCoreReg(PC_REG, &success);
5978     if (!success)
5979       return false;
5980 
5981     uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5982 
5983     EmulateInstruction::Context context;
5984     context.type = EmulateInstruction::eContextImmediate;
5985     context.SetNoArgs();
5986 
5987     if (!WriteCoreReg(context, result, Rd))
5988       return false;
5989   }
5990   return true;
5991 }
5992 
5993 // This instruction performs a bitwise AND of a register value and an immediate
5994 // value, and writes the result to the destination register.  It can optionally
5995 // update the condition flags based on the result.
5996 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
5997                                           const ARMEncoding encoding) {
5998 #if 0
5999     // ARM pseudo code...
6000     if ConditionPassed() then
6001         EncodingSpecificOperations();
6002         result = R[n] AND imm32;
6003         if d == 15 then         // Can only occur for ARM encoding
6004             ALUWritePC(result); // setflags is always FALSE here
6005         else
6006             R[d] = result;
6007             if setflags then
6008                 APSR.N = result<31>;
6009                 APSR.Z = IsZeroBit(result);
6010                 APSR.C = carry;
6011                 // APSR.V unchanged
6012 #endif
6013 
6014   bool success = false;
6015 
6016   if (ConditionPassed(opcode)) {
6017     uint32_t Rd, Rn;
6018     uint32_t
6019         imm32; // the immediate value to be ANDed to the value obtained from Rn
6020     bool setflags;
6021     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6022     switch (encoding) {
6023     case eEncodingT1:
6024       Rd = Bits32(opcode, 11, 8);
6025       Rn = Bits32(opcode, 19, 16);
6026       setflags = BitIsSet(opcode, 20);
6027       imm32 = ThumbExpandImm_C(
6028           opcode, APSR_C,
6029           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6030       // if Rd == '1111' && S == '1' then SEE TST (immediate);
6031       if (Rd == 15 && setflags)
6032         return EmulateTSTImm(opcode, eEncodingT1);
6033       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6034         return false;
6035       break;
6036     case eEncodingA1:
6037       Rd = Bits32(opcode, 15, 12);
6038       Rn = Bits32(opcode, 19, 16);
6039       setflags = BitIsSet(opcode, 20);
6040       imm32 =
6041           ARMExpandImm_C(opcode, APSR_C,
6042                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6043 
6044       if (Rd == 15 && setflags)
6045         return EmulateSUBSPcLrEtc(opcode, encoding);
6046       break;
6047     default:
6048       return false;
6049     }
6050 
6051     // Read the first operand.
6052     uint32_t val1 = ReadCoreReg(Rn, &success);
6053     if (!success)
6054       return false;
6055 
6056     uint32_t result = val1 & imm32;
6057 
6058     EmulateInstruction::Context context;
6059     context.type = EmulateInstruction::eContextImmediate;
6060     context.SetNoArgs();
6061 
6062     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6063       return false;
6064   }
6065   return true;
6066 }
6067 
6068 // This instruction performs a bitwise AND of a register value and an
6069 // optionally-shifted register value, and writes the result to the destination
6070 // register.  It can optionally update the condition flags based on the result.
6071 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6072                                           const ARMEncoding encoding) {
6073 #if 0
6074     // ARM pseudo code...
6075     if ConditionPassed() then
6076         EncodingSpecificOperations();
6077         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6078         result = R[n] AND shifted;
6079         if d == 15 then         // Can only occur for ARM encoding
6080             ALUWritePC(result); // setflags is always FALSE here
6081         else
6082             R[d] = result;
6083             if setflags then
6084                 APSR.N = result<31>;
6085                 APSR.Z = IsZeroBit(result);
6086                 APSR.C = carry;
6087                 // APSR.V unchanged
6088 #endif
6089 
6090   bool success = false;
6091 
6092   if (ConditionPassed(opcode)) {
6093     uint32_t Rd, Rn, Rm;
6094     ARM_ShifterType shift_t;
6095     uint32_t shift_n; // the shift applied to the value read from Rm
6096     bool setflags;
6097     uint32_t carry;
6098     switch (encoding) {
6099     case eEncodingT1:
6100       Rd = Rn = Bits32(opcode, 2, 0);
6101       Rm = Bits32(opcode, 5, 3);
6102       setflags = !InITBlock();
6103       shift_t = SRType_LSL;
6104       shift_n = 0;
6105       break;
6106     case eEncodingT2:
6107       Rd = Bits32(opcode, 11, 8);
6108       Rn = Bits32(opcode, 19, 16);
6109       Rm = Bits32(opcode, 3, 0);
6110       setflags = BitIsSet(opcode, 20);
6111       shift_n = DecodeImmShiftThumb(opcode, shift_t);
6112       // if Rd == '1111' && S == '1' then SEE TST (register);
6113       if (Rd == 15 && setflags)
6114         return EmulateTSTReg(opcode, eEncodingT2);
6115       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6116         return false;
6117       break;
6118     case eEncodingA1:
6119       Rd = Bits32(opcode, 15, 12);
6120       Rn = Bits32(opcode, 19, 16);
6121       Rm = Bits32(opcode, 3, 0);
6122       setflags = BitIsSet(opcode, 20);
6123       shift_n = DecodeImmShiftARM(opcode, shift_t);
6124 
6125       if (Rd == 15 && setflags)
6126         return EmulateSUBSPcLrEtc(opcode, encoding);
6127       break;
6128     default:
6129       return false;
6130     }
6131 
6132     // Read the first operand.
6133     uint32_t val1 = ReadCoreReg(Rn, &success);
6134     if (!success)
6135       return false;
6136 
6137     // Read the second operand.
6138     uint32_t val2 = ReadCoreReg(Rm, &success);
6139     if (!success)
6140       return false;
6141 
6142     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6143     if (!success)
6144       return false;
6145     uint32_t result = val1 & shifted;
6146 
6147     EmulateInstruction::Context context;
6148     context.type = EmulateInstruction::eContextImmediate;
6149     context.SetNoArgs();
6150 
6151     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6152       return false;
6153   }
6154   return true;
6155 }
6156 
6157 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6158 // the complement of an immediate value, and writes the result to the
6159 // destination register.  It can optionally update the condition flags based on
6160 // the result.
6161 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6162                                           const ARMEncoding encoding) {
6163 #if 0
6164     // ARM pseudo code...
6165     if ConditionPassed() then
6166         EncodingSpecificOperations();
6167         result = R[n] AND NOT(imm32);
6168         if d == 15 then         // Can only occur for ARM encoding
6169             ALUWritePC(result); // setflags is always FALSE here
6170         else
6171             R[d] = result;
6172             if setflags then
6173                 APSR.N = result<31>;
6174                 APSR.Z = IsZeroBit(result);
6175                 APSR.C = carry;
6176                 // APSR.V unchanged
6177 #endif
6178 
6179   bool success = false;
6180 
6181   if (ConditionPassed(opcode)) {
6182     uint32_t Rd, Rn;
6183     uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6184                     // the value obtained from Rn
6185     bool setflags;
6186     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6187     switch (encoding) {
6188     case eEncodingT1:
6189       Rd = Bits32(opcode, 11, 8);
6190       Rn = Bits32(opcode, 19, 16);
6191       setflags = BitIsSet(opcode, 20);
6192       imm32 = ThumbExpandImm_C(
6193           opcode, APSR_C,
6194           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6195       if (BadReg(Rd) || BadReg(Rn))
6196         return false;
6197       break;
6198     case eEncodingA1:
6199       Rd = Bits32(opcode, 15, 12);
6200       Rn = Bits32(opcode, 19, 16);
6201       setflags = BitIsSet(opcode, 20);
6202       imm32 =
6203           ARMExpandImm_C(opcode, APSR_C,
6204                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6205 
6206       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6207       // instructions;
6208       if (Rd == 15 && setflags)
6209         return EmulateSUBSPcLrEtc(opcode, encoding);
6210       break;
6211     default:
6212       return false;
6213     }
6214 
6215     // Read the first operand.
6216     uint32_t val1 = ReadCoreReg(Rn, &success);
6217     if (!success)
6218       return false;
6219 
6220     uint32_t result = val1 & ~imm32;
6221 
6222     EmulateInstruction::Context context;
6223     context.type = EmulateInstruction::eContextImmediate;
6224     context.SetNoArgs();
6225 
6226     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6227       return false;
6228   }
6229   return true;
6230 }
6231 
6232 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6233 // the complement of an optionally-shifted register value, and writes the
6234 // result to the destination register. It can optionally update the condition
6235 // flags based on the result.
6236 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6237                                           const ARMEncoding encoding) {
6238 #if 0
6239     // ARM pseudo code...
6240     if ConditionPassed() then
6241         EncodingSpecificOperations();
6242         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6243         result = R[n] AND NOT(shifted);
6244         if d == 15 then         // Can only occur for ARM encoding
6245             ALUWritePC(result); // setflags is always FALSE here
6246         else
6247             R[d] = result;
6248             if setflags then
6249                 APSR.N = result<31>;
6250                 APSR.Z = IsZeroBit(result);
6251                 APSR.C = carry;
6252                 // APSR.V unchanged
6253 #endif
6254 
6255   bool success = false;
6256 
6257   if (ConditionPassed(opcode)) {
6258     uint32_t Rd, Rn, Rm;
6259     ARM_ShifterType shift_t;
6260     uint32_t shift_n; // the shift applied to the value read from Rm
6261     bool setflags;
6262     uint32_t carry;
6263     switch (encoding) {
6264     case eEncodingT1:
6265       Rd = Rn = Bits32(opcode, 2, 0);
6266       Rm = Bits32(opcode, 5, 3);
6267       setflags = !InITBlock();
6268       shift_t = SRType_LSL;
6269       shift_n = 0;
6270       break;
6271     case eEncodingT2:
6272       Rd = Bits32(opcode, 11, 8);
6273       Rn = Bits32(opcode, 19, 16);
6274       Rm = Bits32(opcode, 3, 0);
6275       setflags = BitIsSet(opcode, 20);
6276       shift_n = DecodeImmShiftThumb(opcode, shift_t);
6277       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6278         return false;
6279       break;
6280     case eEncodingA1:
6281       Rd = Bits32(opcode, 15, 12);
6282       Rn = Bits32(opcode, 19, 16);
6283       Rm = Bits32(opcode, 3, 0);
6284       setflags = BitIsSet(opcode, 20);
6285       shift_n = DecodeImmShiftARM(opcode, shift_t);
6286 
6287       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6288       // instructions;
6289       if (Rd == 15 && setflags)
6290         return EmulateSUBSPcLrEtc(opcode, encoding);
6291       break;
6292     default:
6293       return false;
6294     }
6295 
6296     // Read the first operand.
6297     uint32_t val1 = ReadCoreReg(Rn, &success);
6298     if (!success)
6299       return false;
6300 
6301     // Read the second operand.
6302     uint32_t val2 = ReadCoreReg(Rm, &success);
6303     if (!success)
6304       return false;
6305 
6306     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6307     if (!success)
6308       return false;
6309     uint32_t result = val1 & ~shifted;
6310 
6311     EmulateInstruction::Context context;
6312     context.type = EmulateInstruction::eContextImmediate;
6313     context.SetNoArgs();
6314 
6315     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6316       return false;
6317   }
6318   return true;
6319 }
6320 
6321 // LDR (immediate, ARM) calculates an address from a base register value and an
6322 // immediate offset, loads a word
6323 // from memory, and writes it to a register.  It can use offset, post-indexed,
6324 // or pre-indexed addressing.
6325 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6326                                                    const ARMEncoding encoding) {
6327 #if 0
6328     if ConditionPassed() then
6329         EncodingSpecificOperations();
6330         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6331         address = if index then offset_addr else R[n];
6332         data = MemU[address,4];
6333         if wback then R[n] = offset_addr;
6334         if t == 15 then
6335             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6336         elsif UnalignedSupport() || address<1:0> = '00' then
6337             R[t] = data;
6338         else // Can only apply before ARMv7
6339             R[t] = ROR(data, 8*UInt(address<1:0>));
6340 #endif
6341 
6342   bool success = false;
6343 
6344   if (ConditionPassed(opcode)) {
6345     const uint32_t addr_byte_size = GetAddressByteSize();
6346 
6347     uint32_t t;
6348     uint32_t n;
6349     uint32_t imm32;
6350     bool index;
6351     bool add;
6352     bool wback;
6353 
6354     switch (encoding) {
6355     case eEncodingA1:
6356       // if Rn == '1111' then SEE LDR (literal);
6357       // if P == '0' && W == '1' then SEE LDRT;
6358       // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6359       // '000000000100' then SEE POP;
6360       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6361       t = Bits32(opcode, 15, 12);
6362       n = Bits32(opcode, 19, 16);
6363       imm32 = Bits32(opcode, 11, 0);
6364 
6365       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6366       // (W == '1');
6367       index = BitIsSet(opcode, 24);
6368       add = BitIsSet(opcode, 23);
6369       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6370 
6371       // if wback && n == t then UNPREDICTABLE;
6372       if (wback && (n == t))
6373         return false;
6374 
6375       break;
6376 
6377     default:
6378       return false;
6379     }
6380 
6381     addr_t address;
6382     addr_t offset_addr;
6383     addr_t base_address = ReadCoreReg(n, &success);
6384     if (!success)
6385       return false;
6386 
6387     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6388     if (add)
6389       offset_addr = base_address + imm32;
6390     else
6391       offset_addr = base_address - imm32;
6392 
6393     // address = if index then offset_addr else R[n];
6394     if (index)
6395       address = offset_addr;
6396     else
6397       address = base_address;
6398 
6399     // data = MemU[address,4];
6400 
6401     std::optional<RegisterInfo> base_reg =
6402         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6403     EmulateInstruction::Context context;
6404     context.type = eContextRegisterLoad;
6405     context.SetRegisterPlusOffset(*base_reg, address - base_address);
6406 
6407     uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6408     if (!success)
6409       return false;
6410 
6411     // if wback then R[n] = offset_addr;
6412     if (wback) {
6413       context.type = eContextAdjustBaseRegister;
6414       context.SetAddress(offset_addr);
6415       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6416                                  offset_addr))
6417         return false;
6418     }
6419 
6420     // if t == 15 then
6421     if (t == 15) {
6422       // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6423       if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6424         // LoadWritePC (data);
6425         context.type = eContextRegisterLoad;
6426         context.SetRegisterPlusOffset(*base_reg, address - base_address);
6427         LoadWritePC(context, data);
6428       } else
6429         return false;
6430     }
6431     // elsif UnalignedSupport() || address<1:0> = '00' then
6432     else if (UnalignedSupport() ||
6433              (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6434       // R[t] = data;
6435       context.type = eContextRegisterLoad;
6436       context.SetRegisterPlusOffset(*base_reg, address - base_address);
6437       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6438                                  data))
6439         return false;
6440     }
6441     // else // Can only apply before ARMv7
6442     else {
6443       // R[t] = ROR(data, 8*UInt(address<1:0>));
6444       data = ROR(data, Bits32(address, 1, 0), &success);
6445       if (!success)
6446         return false;
6447       context.type = eContextRegisterLoad;
6448       context.SetImmediate(data);
6449       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6450                                  data))
6451         return false;
6452     }
6453   }
6454   return true;
6455 }
6456 
6457 // LDR (register) calculates an address from a base register value and an offset
6458 // register value, loads a word
6459 // from memory, and writes it to a register.  The offset register value can
6460 // optionally be shifted.
6461 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6462                                                const ARMEncoding encoding) {
6463 #if 0
6464     if ConditionPassed() then
6465         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6466         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6467         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6468         address = if index then offset_addr else R[n];
6469         data = MemU[address,4];
6470         if wback then R[n] = offset_addr;
6471         if t == 15 then
6472             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6473         elsif UnalignedSupport() || address<1:0> = '00' then
6474             R[t] = data;
6475         else // Can only apply before ARMv7
6476             if CurrentInstrSet() == InstrSet_ARM then
6477                 R[t] = ROR(data, 8*UInt(address<1:0>));
6478             else
6479                 R[t] = bits(32) UNKNOWN;
6480 #endif
6481 
6482   bool success = false;
6483 
6484   if (ConditionPassed(opcode)) {
6485     const uint32_t addr_byte_size = GetAddressByteSize();
6486 
6487     uint32_t t;
6488     uint32_t n;
6489     uint32_t m;
6490     bool index;
6491     bool add;
6492     bool wback;
6493     ARM_ShifterType shift_t;
6494     uint32_t shift_n;
6495 
6496     switch (encoding) {
6497     case eEncodingT1:
6498       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6499       // in ThumbEE";
6500       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6501       t = Bits32(opcode, 2, 0);
6502       n = Bits32(opcode, 5, 3);
6503       m = Bits32(opcode, 8, 6);
6504 
6505       // index = TRUE; add = TRUE; wback = FALSE;
6506       index = true;
6507       add = true;
6508       wback = false;
6509 
6510       // (shift_t, shift_n) = (SRType_LSL, 0);
6511       shift_t = SRType_LSL;
6512       shift_n = 0;
6513 
6514       break;
6515 
6516     case eEncodingT2:
6517       // if Rn == '1111' then SEE LDR (literal);
6518       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6519       t = Bits32(opcode, 15, 12);
6520       n = Bits32(opcode, 19, 16);
6521       m = Bits32(opcode, 3, 0);
6522 
6523       // index = TRUE; add = TRUE; wback = FALSE;
6524       index = true;
6525       add = true;
6526       wback = false;
6527 
6528       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6529       shift_t = SRType_LSL;
6530       shift_n = Bits32(opcode, 5, 4);
6531 
6532       // if BadReg(m) then UNPREDICTABLE;
6533       if (BadReg(m))
6534         return false;
6535 
6536       // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6537       if ((t == 15) && InITBlock() && !LastInITBlock())
6538         return false;
6539 
6540       break;
6541 
6542     case eEncodingA1: {
6543       // if P == '0' && W == '1' then SEE LDRT;
6544       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6545       t = Bits32(opcode, 15, 12);
6546       n = Bits32(opcode, 19, 16);
6547       m = Bits32(opcode, 3, 0);
6548 
6549       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6550       // (W == '1');
6551       index = BitIsSet(opcode, 24);
6552       add = BitIsSet(opcode, 23);
6553       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6554 
6555       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6556       uint32_t type = Bits32(opcode, 6, 5);
6557       uint32_t imm5 = Bits32(opcode, 11, 7);
6558       shift_n = DecodeImmShift(type, imm5, shift_t);
6559 
6560       // if m == 15 then UNPREDICTABLE;
6561       if (m == 15)
6562         return false;
6563 
6564       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6565       if (wback && ((n == 15) || (n == t)))
6566         return false;
6567     } break;
6568 
6569     default:
6570       return false;
6571     }
6572 
6573     uint32_t Rm =
6574         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6575     if (!success)
6576       return false;
6577 
6578     uint32_t Rn =
6579         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6580     if (!success)
6581       return false;
6582 
6583     addr_t offset_addr;
6584     addr_t address;
6585 
6586     // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is
6587     // an application level alias for the CPSR".
6588     addr_t offset =
6589         Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6590     if (!success)
6591       return false;
6592 
6593     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6594     if (add)
6595       offset_addr = Rn + offset;
6596     else
6597       offset_addr = Rn - offset;
6598 
6599     // address = if index then offset_addr else R[n];
6600     if (index)
6601       address = offset_addr;
6602     else
6603       address = Rn;
6604 
6605     // data = MemU[address,4];
6606     std::optional<RegisterInfo> base_reg =
6607         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6608     EmulateInstruction::Context context;
6609     context.type = eContextRegisterLoad;
6610     context.SetRegisterPlusOffset(*base_reg, address - Rn);
6611 
6612     uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6613     if (!success)
6614       return false;
6615 
6616     // if wback then R[n] = offset_addr;
6617     if (wback) {
6618       context.type = eContextAdjustBaseRegister;
6619       context.SetAddress(offset_addr);
6620       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6621                                  offset_addr))
6622         return false;
6623     }
6624 
6625     // if t == 15 then
6626     if (t == 15) {
6627       // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6628       if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6629         context.type = eContextRegisterLoad;
6630         context.SetRegisterPlusOffset(*base_reg, address - Rn);
6631         LoadWritePC(context, data);
6632       } else
6633         return false;
6634     }
6635     // elsif UnalignedSupport() || address<1:0> = '00' then
6636     else if (UnalignedSupport() ||
6637              (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6638       // R[t] = data;
6639       context.type = eContextRegisterLoad;
6640       context.SetRegisterPlusOffset(*base_reg, address - Rn);
6641       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6642                                  data))
6643         return false;
6644     } else // Can only apply before ARMv7
6645     {
6646       // if CurrentInstrSet() == InstrSet_ARM then
6647       if (CurrentInstrSet() == eModeARM) {
6648         // R[t] = ROR(data, 8*UInt(address<1:0>));
6649         data = ROR(data, Bits32(address, 1, 0), &success);
6650         if (!success)
6651           return false;
6652         context.type = eContextRegisterLoad;
6653         context.SetImmediate(data);
6654         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6655                                    data))
6656           return false;
6657       } else {
6658         // R[t] = bits(32) UNKNOWN;
6659         WriteBits32Unknown(t);
6660       }
6661     }
6662   }
6663   return true;
6664 }
6665 
6666 // LDRB (immediate, Thumb)
6667 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6668                                                  const ARMEncoding encoding) {
6669 #if 0
6670     if ConditionPassed() then
6671         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6672         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6673         address = if index then offset_addr else R[n];
6674         R[t] = ZeroExtend(MemU[address,1], 32);
6675         if wback then R[n] = offset_addr;
6676 #endif
6677 
6678   bool success = false;
6679 
6680   if (ConditionPassed(opcode)) {
6681     uint32_t t;
6682     uint32_t n;
6683     uint32_t imm32;
6684     bool index;
6685     bool add;
6686     bool wback;
6687 
6688     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6689     switch (encoding) {
6690     case eEncodingT1:
6691       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6692       t = Bits32(opcode, 2, 0);
6693       n = Bits32(opcode, 5, 3);
6694       imm32 = Bits32(opcode, 10, 6);
6695 
6696       // index = TRUE; add = TRUE; wback = FALSE;
6697       index = true;
6698       add = true;
6699       wback = false;
6700 
6701       break;
6702 
6703     case eEncodingT2:
6704       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6705       t = Bits32(opcode, 15, 12);
6706       n = Bits32(opcode, 19, 16);
6707       imm32 = Bits32(opcode, 11, 0);
6708 
6709       // index = TRUE; add = TRUE; wback = FALSE;
6710       index = true;
6711       add = true;
6712       wback = false;
6713 
6714       // if Rt == '1111' then SEE PLD;
6715       if (t == 15)
6716         return false; // PLD is not implemented yet
6717 
6718       // if Rn == '1111' then SEE LDRB (literal);
6719       if (n == 15)
6720         return EmulateLDRBLiteral(opcode, eEncodingT1);
6721 
6722       // if t == 13 then UNPREDICTABLE;
6723       if (t == 13)
6724         return false;
6725 
6726       break;
6727 
6728     case eEncodingT3:
6729       // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6730       // if P == '0' && W == '0' then UNDEFINED;
6731       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6732         return false;
6733 
6734       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6735       t = Bits32(opcode, 15, 12);
6736       n = Bits32(opcode, 19, 16);
6737       imm32 = Bits32(opcode, 7, 0);
6738 
6739       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6740       index = BitIsSet(opcode, 10);
6741       add = BitIsSet(opcode, 9);
6742       wback = BitIsSet(opcode, 8);
6743 
6744       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6745       if (t == 15)
6746         return false; // PLD is not implemented yet
6747 
6748       // if Rn == '1111' then SEE LDRB (literal);
6749       if (n == 15)
6750         return EmulateLDRBLiteral(opcode, eEncodingT1);
6751 
6752       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6753       if (BadReg(t) || (wback && (n == t)))
6754         return false;
6755 
6756       break;
6757 
6758     default:
6759       return false;
6760     }
6761 
6762     uint32_t Rn =
6763         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6764     if (!success)
6765       return false;
6766 
6767     addr_t address;
6768     addr_t offset_addr;
6769 
6770     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6771     if (add)
6772       offset_addr = Rn + imm32;
6773     else
6774       offset_addr = Rn - imm32;
6775 
6776     // address = if index then offset_addr else R[n];
6777     if (index)
6778       address = offset_addr;
6779     else
6780       address = Rn;
6781 
6782     // R[t] = ZeroExtend(MemU[address,1], 32);
6783     std::optional<RegisterInfo> base_reg =
6784         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6785     std::optional<RegisterInfo> data_reg =
6786         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
6787 
6788     EmulateInstruction::Context context;
6789     context.type = eContextRegisterLoad;
6790     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
6791 
6792     uint64_t data = MemURead(context, address, 1, 0, &success);
6793     if (!success)
6794       return false;
6795 
6796     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6797       return false;
6798 
6799     // if wback then R[n] = offset_addr;
6800     if (wback) {
6801       context.type = eContextAdjustBaseRegister;
6802       context.SetAddress(offset_addr);
6803       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6804                                  offset_addr))
6805         return false;
6806     }
6807   }
6808   return true;
6809 }
6810 
6811 // LDRB (literal) calculates an address from the PC value and an immediate
6812 // offset, loads a byte from memory,
6813 // zero-extends it to form a 32-bit word and writes it to a register.
6814 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6815                                                const ARMEncoding encoding) {
6816 #if 0
6817     if ConditionPassed() then
6818         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6819         base = Align(PC,4);
6820         address = if add then (base + imm32) else (base - imm32);
6821         R[t] = ZeroExtend(MemU[address,1], 32);
6822 #endif
6823 
6824   bool success = false;
6825 
6826   if (ConditionPassed(opcode)) {
6827     uint32_t t;
6828     uint32_t imm32;
6829     bool add;
6830     switch (encoding) {
6831     case eEncodingT1:
6832       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6833       t = Bits32(opcode, 15, 12);
6834       imm32 = Bits32(opcode, 11, 0);
6835       add = BitIsSet(opcode, 23);
6836 
6837       // if Rt == '1111' then SEE PLD;
6838       if (t == 15)
6839         return false; // PLD is not implemented yet
6840 
6841       // if t == 13 then UNPREDICTABLE;
6842       if (t == 13)
6843         return false;
6844 
6845       break;
6846 
6847     case eEncodingA1:
6848       // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6849       t = Bits32(opcode, 15, 12);
6850       imm32 = Bits32(opcode, 11, 0);
6851       add = BitIsSet(opcode, 23);
6852 
6853       // if t == 15 then UNPREDICTABLE;
6854       if (t == 15)
6855         return false;
6856       break;
6857 
6858     default:
6859       return false;
6860     }
6861 
6862     // base = Align(PC,4);
6863     uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6864     if (!success)
6865       return false;
6866 
6867     uint32_t base = AlignPC(pc_val);
6868 
6869     addr_t address;
6870     // address = if add then (base + imm32) else (base - imm32);
6871     if (add)
6872       address = base + imm32;
6873     else
6874       address = base - imm32;
6875 
6876     // R[t] = ZeroExtend(MemU[address,1], 32);
6877     EmulateInstruction::Context context;
6878     context.type = eContextRelativeBranchImmediate;
6879     context.SetImmediate(address - base);
6880 
6881     uint64_t data = MemURead(context, address, 1, 0, &success);
6882     if (!success)
6883       return false;
6884 
6885     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6886       return false;
6887   }
6888   return true;
6889 }
6890 
6891 // LDRB (register) calculates an address from a base register value and an
6892 // offset rigister value, loads a byte from memory, zero-extends it to form a
6893 // 32-bit word, and writes it to a register. The offset register value can
6894 // optionally be shifted.
6895 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6896                                                 const ARMEncoding encoding) {
6897 #if 0
6898     if ConditionPassed() then
6899         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6900         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6901         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6902         address = if index then offset_addr else R[n];
6903         R[t] = ZeroExtend(MemU[address,1],32);
6904         if wback then R[n] = offset_addr;
6905 #endif
6906 
6907   bool success = false;
6908 
6909   if (ConditionPassed(opcode)) {
6910     uint32_t t;
6911     uint32_t n;
6912     uint32_t m;
6913     bool index;
6914     bool add;
6915     bool wback;
6916     ARM_ShifterType shift_t;
6917     uint32_t shift_n;
6918 
6919     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6920     switch (encoding) {
6921     case eEncodingT1:
6922       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6923       t = Bits32(opcode, 2, 0);
6924       n = Bits32(opcode, 5, 3);
6925       m = Bits32(opcode, 8, 6);
6926 
6927       // index = TRUE; add = TRUE; wback = FALSE;
6928       index = true;
6929       add = true;
6930       wback = false;
6931 
6932       // (shift_t, shift_n) = (SRType_LSL, 0);
6933       shift_t = SRType_LSL;
6934       shift_n = 0;
6935       break;
6936 
6937     case eEncodingT2:
6938       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6939       t = Bits32(opcode, 15, 12);
6940       n = Bits32(opcode, 19, 16);
6941       m = Bits32(opcode, 3, 0);
6942 
6943       // index = TRUE; add = TRUE; wback = FALSE;
6944       index = true;
6945       add = true;
6946       wback = false;
6947 
6948       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6949       shift_t = SRType_LSL;
6950       shift_n = Bits32(opcode, 5, 4);
6951 
6952       // if Rt == '1111' then SEE PLD;
6953       if (t == 15)
6954         return false; // PLD is not implemented yet
6955 
6956       // if Rn == '1111' then SEE LDRB (literal);
6957       if (n == 15)
6958         return EmulateLDRBLiteral(opcode, eEncodingT1);
6959 
6960       // if t == 13 || BadReg(m) then UNPREDICTABLE;
6961       if ((t == 13) || BadReg(m))
6962         return false;
6963       break;
6964 
6965     case eEncodingA1: {
6966       // if P == '0' && W == '1' then SEE LDRBT;
6967       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6968       t = Bits32(opcode, 15, 12);
6969       n = Bits32(opcode, 19, 16);
6970       m = Bits32(opcode, 3, 0);
6971 
6972       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6973       // (W == '1');
6974       index = BitIsSet(opcode, 24);
6975       add = BitIsSet(opcode, 23);
6976       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6977 
6978       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6979       uint32_t type = Bits32(opcode, 6, 5);
6980       uint32_t imm5 = Bits32(opcode, 11, 7);
6981       shift_n = DecodeImmShift(type, imm5, shift_t);
6982 
6983       // if t == 15 || m == 15 then UNPREDICTABLE;
6984       if ((t == 15) || (m == 15))
6985         return false;
6986 
6987       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6988       if (wback && ((n == 15) || (n == t)))
6989         return false;
6990     } break;
6991 
6992     default:
6993       return false;
6994     }
6995 
6996     addr_t offset_addr;
6997     addr_t address;
6998 
6999     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7000     uint32_t Rm =
7001         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7002     if (!success)
7003       return false;
7004 
7005     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7006     if (!success)
7007       return false;
7008 
7009     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7010     uint32_t Rn =
7011         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7012     if (!success)
7013       return false;
7014 
7015     if (add)
7016       offset_addr = Rn + offset;
7017     else
7018       offset_addr = Rn - offset;
7019 
7020     // address = if index then offset_addr else R[n];
7021     if (index)
7022       address = offset_addr;
7023     else
7024       address = Rn;
7025 
7026     // R[t] = ZeroExtend(MemU[address,1],32);
7027     std::optional<RegisterInfo> base_reg =
7028         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7029 
7030     EmulateInstruction::Context context;
7031     context.type = eContextRegisterLoad;
7032     context.SetRegisterPlusOffset(*base_reg, address - Rn);
7033 
7034     uint64_t data = MemURead(context, address, 1, 0, &success);
7035     if (!success)
7036       return false;
7037 
7038     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7039       return false;
7040 
7041     // if wback then R[n] = offset_addr;
7042     if (wback) {
7043       context.type = eContextAdjustBaseRegister;
7044       context.SetAddress(offset_addr);
7045       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7046                                  offset_addr))
7047         return false;
7048     }
7049   }
7050   return true;
7051 }
7052 
7053 // LDRH (immediate, Thumb) calculates an address from a base register value and
7054 // an immediate offset, loads a
7055 // halfword from memory, zero-extends it to form a 32-bit word, and writes it
7056 // to a register.  It can use offset, post-indexed, or pre-indexed addressing.
7057 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7058                                                  const ARMEncoding encoding) {
7059 #if 0
7060     if ConditionPassed() then
7061         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7062         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7063         address = if index then offset_addr else R[n];
7064         data = MemU[address,2];
7065         if wback then R[n] = offset_addr;
7066         if UnalignedSupport() || address<0> = '0' then
7067             R[t] = ZeroExtend(data, 32);
7068         else // Can only apply before ARMv7
7069             R[t] = bits(32) UNKNOWN;
7070 #endif
7071 
7072   bool success = false;
7073 
7074   if (ConditionPassed(opcode)) {
7075     uint32_t t;
7076     uint32_t n;
7077     uint32_t imm32;
7078     bool index;
7079     bool add;
7080     bool wback;
7081 
7082     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7083     switch (encoding) {
7084     case eEncodingT1:
7085       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7086       t = Bits32(opcode, 2, 0);
7087       n = Bits32(opcode, 5, 3);
7088       imm32 = Bits32(opcode, 10, 6) << 1;
7089 
7090       // index = TRUE; add = TRUE; wback = FALSE;
7091       index = true;
7092       add = true;
7093       wback = false;
7094 
7095       break;
7096 
7097     case eEncodingT2:
7098       // if Rt == '1111' then SEE "Unallocated memory hints";
7099       // if Rn == '1111' then SEE LDRH (literal);
7100       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7101       t = Bits32(opcode, 15, 12);
7102       n = Bits32(opcode, 19, 16);
7103       imm32 = Bits32(opcode, 11, 0);
7104 
7105       // index = TRUE; add = TRUE; wback = FALSE;
7106       index = true;
7107       add = true;
7108       wback = false;
7109 
7110       // if t == 13 then UNPREDICTABLE;
7111       if (t == 13)
7112         return false;
7113       break;
7114 
7115     case eEncodingT3:
7116       // if Rn == '1111' then SEE LDRH (literal);
7117       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7118       // "Unallocated memory hints";
7119       // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7120       // if P == '0' && W == '0' then UNDEFINED;
7121       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7122         return false;
7123 
7124       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7125       t = Bits32(opcode, 15, 12);
7126       n = Bits32(opcode, 19, 16);
7127       imm32 = Bits32(opcode, 7, 0);
7128 
7129       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7130       index = BitIsSet(opcode, 10);
7131       add = BitIsSet(opcode, 9);
7132       wback = BitIsSet(opcode, 8);
7133 
7134       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7135       if (BadReg(t) || (wback && (n == t)))
7136         return false;
7137       break;
7138 
7139     default:
7140       return false;
7141     }
7142 
7143     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7144     uint32_t Rn =
7145         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7146     if (!success)
7147       return false;
7148 
7149     addr_t offset_addr;
7150     addr_t address;
7151 
7152     if (add)
7153       offset_addr = Rn + imm32;
7154     else
7155       offset_addr = Rn - imm32;
7156 
7157     // address = if index then offset_addr else R[n];
7158     if (index)
7159       address = offset_addr;
7160     else
7161       address = Rn;
7162 
7163     // data = MemU[address,2];
7164     std::optional<RegisterInfo> base_reg =
7165         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7166 
7167     EmulateInstruction::Context context;
7168     context.type = eContextRegisterLoad;
7169     context.SetRegisterPlusOffset(*base_reg, address - Rn);
7170 
7171     uint64_t data = MemURead(context, address, 2, 0, &success);
7172     if (!success)
7173       return false;
7174 
7175     // if wback then R[n] = offset_addr;
7176     if (wback) {
7177       context.type = eContextAdjustBaseRegister;
7178       context.SetAddress(offset_addr);
7179       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7180                                  offset_addr))
7181         return false;
7182     }
7183 
7184     // if UnalignedSupport() || address<0> = '0' then
7185     if (UnalignedSupport() || BitIsClear(address, 0)) {
7186       // R[t] = ZeroExtend(data, 32);
7187       context.type = eContextRegisterLoad;
7188       context.SetRegisterPlusOffset(*base_reg, address - Rn);
7189       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7190                                  data))
7191         return false;
7192     } else // Can only apply before ARMv7
7193     {
7194       // R[t] = bits(32) UNKNOWN;
7195       WriteBits32Unknown(t);
7196     }
7197   }
7198   return true;
7199 }
7200 
7201 // LDRH (literal) calculates an address from the PC value and an immediate
7202 // offset, loads a halfword from memory,
7203 // zero-extends it to form a 32-bit word, and writes it to a register.
7204 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7205                                                const ARMEncoding encoding) {
7206 #if 0
7207     if ConditionPassed() then
7208         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7209         base = Align(PC,4);
7210         address = if add then (base + imm32) else (base - imm32);
7211         data = MemU[address,2];
7212         if UnalignedSupport() || address<0> = '0' then
7213             R[t] = ZeroExtend(data, 32);
7214         else // Can only apply before ARMv7
7215             R[t] = bits(32) UNKNOWN;
7216 #endif
7217 
7218   bool success = false;
7219 
7220   if (ConditionPassed(opcode)) {
7221     uint32_t t;
7222     uint32_t imm32;
7223     bool add;
7224 
7225     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7226     switch (encoding) {
7227     case eEncodingT1:
7228       // if Rt == '1111' then SEE "Unallocated memory hints";
7229       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7230       t = Bits32(opcode, 15, 12);
7231       imm32 = Bits32(opcode, 11, 0);
7232       add = BitIsSet(opcode, 23);
7233 
7234       // if t == 13 then UNPREDICTABLE;
7235       if (t == 13)
7236         return false;
7237 
7238       break;
7239 
7240     case eEncodingA1: {
7241       uint32_t imm4H = Bits32(opcode, 11, 8);
7242       uint32_t imm4L = Bits32(opcode, 3, 0);
7243 
7244       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7245       t = Bits32(opcode, 15, 12);
7246       imm32 = (imm4H << 4) | imm4L;
7247       add = BitIsSet(opcode, 23);
7248 
7249       // if t == 15 then UNPREDICTABLE;
7250       if (t == 15)
7251         return false;
7252       break;
7253     }
7254 
7255     default:
7256       return false;
7257     }
7258 
7259     // base = Align(PC,4);
7260     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7261     if (!success)
7262       return false;
7263 
7264     addr_t base = AlignPC(pc_value);
7265     addr_t address;
7266 
7267     // address = if add then (base + imm32) else (base - imm32);
7268     if (add)
7269       address = base + imm32;
7270     else
7271       address = base - imm32;
7272 
7273     // data = MemU[address,2];
7274     std::optional<RegisterInfo> base_reg =
7275         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7276 
7277     EmulateInstruction::Context context;
7278     context.type = eContextRegisterLoad;
7279     context.SetRegisterPlusOffset(*base_reg, address - base);
7280 
7281     uint64_t data = MemURead(context, address, 2, 0, &success);
7282     if (!success)
7283       return false;
7284 
7285     // if UnalignedSupport() || address<0> = '0' then
7286     if (UnalignedSupport() || BitIsClear(address, 0)) {
7287       // R[t] = ZeroExtend(data, 32);
7288       context.type = eContextRegisterLoad;
7289       context.SetRegisterPlusOffset(*base_reg, address - base);
7290       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7291                                  data))
7292         return false;
7293 
7294     } else // Can only apply before ARMv7
7295     {
7296       // R[t] = bits(32) UNKNOWN;
7297       WriteBits32Unknown(t);
7298     }
7299   }
7300   return true;
7301 }
7302 
7303 // LDRH (literal) calculates an address from a base register value and an offset
7304 // register value, loads a halfword
7305 // from memory, zero-extends it to form a 32-bit word, and writes it to a
7306 // register.  The offset register value can be shifted left by 0, 1, 2, or 3
7307 // bits.
7308 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7309                                                 const ARMEncoding encoding) {
7310 #if 0
7311     if ConditionPassed() then
7312         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7313         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7314         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7315         address = if index then offset_addr else R[n];
7316         data = MemU[address,2];
7317         if wback then R[n] = offset_addr;
7318         if UnalignedSupport() || address<0> = '0' then
7319             R[t] = ZeroExtend(data, 32);
7320         else // Can only apply before ARMv7
7321             R[t] = bits(32) UNKNOWN;
7322 #endif
7323 
7324   bool success = false;
7325 
7326   if (ConditionPassed(opcode)) {
7327     uint32_t t;
7328     uint32_t n;
7329     uint32_t m;
7330     bool index;
7331     bool add;
7332     bool wback;
7333     ARM_ShifterType shift_t;
7334     uint32_t shift_n;
7335 
7336     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7337     switch (encoding) {
7338     case eEncodingT1:
7339       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7340       // in ThumbEE";
7341       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7342       t = Bits32(opcode, 2, 0);
7343       n = Bits32(opcode, 5, 3);
7344       m = Bits32(opcode, 8, 6);
7345 
7346       // index = TRUE; add = TRUE; wback = FALSE;
7347       index = true;
7348       add = true;
7349       wback = false;
7350 
7351       // (shift_t, shift_n) = (SRType_LSL, 0);
7352       shift_t = SRType_LSL;
7353       shift_n = 0;
7354 
7355       break;
7356 
7357     case eEncodingT2:
7358       // if Rn == '1111' then SEE LDRH (literal);
7359       // if Rt == '1111' then SEE "Unallocated memory hints";
7360       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7361       t = Bits32(opcode, 15, 12);
7362       n = Bits32(opcode, 19, 16);
7363       m = Bits32(opcode, 3, 0);
7364 
7365       // index = TRUE; add = TRUE; wback = FALSE;
7366       index = true;
7367       add = true;
7368       wback = false;
7369 
7370       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7371       shift_t = SRType_LSL;
7372       shift_n = Bits32(opcode, 5, 4);
7373 
7374       // if t == 13 || BadReg(m) then UNPREDICTABLE;
7375       if ((t == 13) || BadReg(m))
7376         return false;
7377       break;
7378 
7379     case eEncodingA1:
7380       // if P == '0' && W == '1' then SEE LDRHT;
7381       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7382       t = Bits32(opcode, 15, 12);
7383       n = Bits32(opcode, 19, 16);
7384       m = Bits32(opcode, 3, 0);
7385 
7386       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7387       // (W == '1');
7388       index = BitIsSet(opcode, 24);
7389       add = BitIsSet(opcode, 23);
7390       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7391 
7392       // (shift_t, shift_n) = (SRType_LSL, 0);
7393       shift_t = SRType_LSL;
7394       shift_n = 0;
7395 
7396       // if t == 15 || m == 15 then UNPREDICTABLE;
7397       if ((t == 15) || (m == 15))
7398         return false;
7399 
7400       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7401       if (wback && ((n == 15) || (n == t)))
7402         return false;
7403 
7404       break;
7405 
7406     default:
7407       return false;
7408     }
7409 
7410     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7411 
7412     uint64_t Rm =
7413         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7414     if (!success)
7415       return false;
7416 
7417     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7418     if (!success)
7419       return false;
7420 
7421     addr_t offset_addr;
7422     addr_t address;
7423 
7424     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7425     uint64_t Rn =
7426         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7427     if (!success)
7428       return false;
7429 
7430     if (add)
7431       offset_addr = Rn + offset;
7432     else
7433       offset_addr = Rn - offset;
7434 
7435     // address = if index then offset_addr else R[n];
7436     if (index)
7437       address = offset_addr;
7438     else
7439       address = Rn;
7440 
7441     // data = MemU[address,2];
7442     std::optional<RegisterInfo> base_reg =
7443         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7444     std::optional<RegisterInfo> offset_reg =
7445         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
7446 
7447     EmulateInstruction::Context context;
7448     context.type = eContextRegisterLoad;
7449     context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7450     uint64_t data = MemURead(context, address, 2, 0, &success);
7451     if (!success)
7452       return false;
7453 
7454     // if wback then R[n] = offset_addr;
7455     if (wback) {
7456       context.type = eContextAdjustBaseRegister;
7457       context.SetAddress(offset_addr);
7458       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7459                                  offset_addr))
7460         return false;
7461     }
7462 
7463     // if UnalignedSupport() || address<0> = '0' then
7464     if (UnalignedSupport() || BitIsClear(address, 0)) {
7465       // R[t] = ZeroExtend(data, 32);
7466       context.type = eContextRegisterLoad;
7467       context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7468       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7469                                  data))
7470         return false;
7471     } else // Can only apply before ARMv7
7472     {
7473       // R[t] = bits(32) UNKNOWN;
7474       WriteBits32Unknown(t);
7475     }
7476   }
7477   return true;
7478 }
7479 
7480 // LDRSB (immediate) calculates an address from a base register value and an
7481 // immediate offset, loads a byte from
7482 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7483 // It can use offset, post-indexed, or pre-indexed addressing.
7484 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7485                                                   const ARMEncoding encoding) {
7486 #if 0
7487     if ConditionPassed() then
7488         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7489         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7490         address = if index then offset_addr else R[n];
7491         R[t] = SignExtend(MemU[address,1], 32);
7492         if wback then R[n] = offset_addr;
7493 #endif
7494 
7495   bool success = false;
7496 
7497   if (ConditionPassed(opcode)) {
7498     uint32_t t;
7499     uint32_t n;
7500     uint32_t imm32;
7501     bool index;
7502     bool add;
7503     bool wback;
7504 
7505     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7506     switch (encoding) {
7507     case eEncodingT1:
7508       // if Rt == '1111' then SEE PLI;
7509       // if Rn == '1111' then SEE LDRSB (literal);
7510       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7511       t = Bits32(opcode, 15, 12);
7512       n = Bits32(opcode, 19, 16);
7513       imm32 = Bits32(opcode, 11, 0);
7514 
7515       // index = TRUE; add = TRUE; wback = FALSE;
7516       index = true;
7517       add = true;
7518       wback = false;
7519 
7520       // if t == 13 then UNPREDICTABLE;
7521       if (t == 13)
7522         return false;
7523 
7524       break;
7525 
7526     case eEncodingT2:
7527       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7528       // if Rn == '1111' then SEE LDRSB (literal);
7529       // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7530       // if P == '0' && W == '0' then UNDEFINED;
7531       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7532         return false;
7533 
7534       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7535       t = Bits32(opcode, 15, 12);
7536       n = Bits32(opcode, 19, 16);
7537       imm32 = Bits32(opcode, 7, 0);
7538 
7539       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7540       index = BitIsSet(opcode, 10);
7541       add = BitIsSet(opcode, 9);
7542       wback = BitIsSet(opcode, 8);
7543 
7544       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7545       if (((t == 13) ||
7546            ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7547                           BitIsSet(opcode, 8)))) ||
7548           (wback && (n == t)))
7549         return false;
7550 
7551       break;
7552 
7553     case eEncodingA1: {
7554       // if Rn == '1111' then SEE LDRSB (literal);
7555       // if P == '0' && W == '1' then SEE LDRSBT;
7556       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7557       t = Bits32(opcode, 15, 12);
7558       n = Bits32(opcode, 19, 16);
7559 
7560       uint32_t imm4H = Bits32(opcode, 11, 8);
7561       uint32_t imm4L = Bits32(opcode, 3, 0);
7562       imm32 = (imm4H << 4) | imm4L;
7563 
7564       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7565       // (W == '1');
7566       index = BitIsSet(opcode, 24);
7567       add = BitIsSet(opcode, 23);
7568       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7569 
7570       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7571       if ((t == 15) || (wback && (n == t)))
7572         return false;
7573 
7574       break;
7575     }
7576 
7577     default:
7578       return false;
7579     }
7580 
7581     uint64_t Rn = ReadCoreReg(n, &success);
7582     if (!success)
7583       return false;
7584 
7585     addr_t offset_addr;
7586     addr_t address;
7587 
7588     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7589     if (add)
7590       offset_addr = Rn + imm32;
7591     else
7592       offset_addr = Rn - imm32;
7593 
7594     // address = if index then offset_addr else R[n];
7595     if (index)
7596       address = offset_addr;
7597     else
7598       address = Rn;
7599 
7600     // R[t] = SignExtend(MemU[address,1], 32);
7601     std::optional<RegisterInfo> base_reg =
7602         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7603 
7604     EmulateInstruction::Context context;
7605     context.type = eContextRegisterLoad;
7606     context.SetRegisterPlusOffset(*base_reg, address - Rn);
7607 
7608     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7609     if (!success)
7610       return false;
7611 
7612     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7613     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7614                                (uint64_t)signed_data))
7615       return false;
7616 
7617     // if wback then R[n] = offset_addr;
7618     if (wback) {
7619       context.type = eContextAdjustBaseRegister;
7620       context.SetAddress(offset_addr);
7621       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7622                                  offset_addr))
7623         return false;
7624     }
7625   }
7626 
7627   return true;
7628 }
7629 
7630 // LDRSB (literal) calculates an address from the PC value and an immediate
7631 // offset, loads a byte from memory,
7632 // sign-extends it to form a 32-bit word, and writes tit to a register.
7633 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7634                                                 const ARMEncoding encoding) {
7635 #if 0
7636     if ConditionPassed() then
7637         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7638         base = Align(PC,4);
7639         address = if add then (base + imm32) else (base - imm32);
7640         R[t] = SignExtend(MemU[address,1], 32);
7641 #endif
7642 
7643   bool success = false;
7644 
7645   if (ConditionPassed(opcode)) {
7646     uint32_t t;
7647     uint32_t imm32;
7648     bool add;
7649 
7650     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7651     switch (encoding) {
7652     case eEncodingT1:
7653       // if Rt == '1111' then SEE PLI;
7654       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7655       t = Bits32(opcode, 15, 12);
7656       imm32 = Bits32(opcode, 11, 0);
7657       add = BitIsSet(opcode, 23);
7658 
7659       // if t == 13 then UNPREDICTABLE;
7660       if (t == 13)
7661         return false;
7662 
7663       break;
7664 
7665     case eEncodingA1: {
7666       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7667       t = Bits32(opcode, 15, 12);
7668       uint32_t imm4H = Bits32(opcode, 11, 8);
7669       uint32_t imm4L = Bits32(opcode, 3, 0);
7670       imm32 = (imm4H << 4) | imm4L;
7671       add = BitIsSet(opcode, 23);
7672 
7673       // if t == 15 then UNPREDICTABLE;
7674       if (t == 15)
7675         return false;
7676 
7677       break;
7678     }
7679 
7680     default:
7681       return false;
7682     }
7683 
7684     // base = Align(PC,4);
7685     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7686     if (!success)
7687       return false;
7688     uint64_t base = AlignPC(pc_value);
7689 
7690     // address = if add then (base + imm32) else (base - imm32);
7691     addr_t address;
7692     if (add)
7693       address = base + imm32;
7694     else
7695       address = base - imm32;
7696 
7697     // R[t] = SignExtend(MemU[address,1], 32);
7698     std::optional<RegisterInfo> base_reg =
7699         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7700 
7701     EmulateInstruction::Context context;
7702     context.type = eContextRegisterLoad;
7703     context.SetRegisterPlusOffset(*base_reg, address - base);
7704 
7705     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7706     if (!success)
7707       return false;
7708 
7709     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7710     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7711                                (uint64_t)signed_data))
7712       return false;
7713   }
7714   return true;
7715 }
7716 
7717 // LDRSB (register) calculates an address from a base register value and an
7718 // offset register value, loadsa byte from
7719 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7720 // The offset register value can be shifted left by 0, 1, 2, or 3 bits.
7721 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7722                                                  const ARMEncoding encoding) {
7723 #if 0
7724     if ConditionPassed() then
7725         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7726         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7727         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7728         address = if index then offset_addr else R[n];
7729         R[t] = SignExtend(MemU[address,1], 32);
7730         if wback then R[n] = offset_addr;
7731 #endif
7732 
7733   bool success = false;
7734 
7735   if (ConditionPassed(opcode)) {
7736     uint32_t t;
7737     uint32_t n;
7738     uint32_t m;
7739     bool index;
7740     bool add;
7741     bool wback;
7742     ARM_ShifterType shift_t;
7743     uint32_t shift_n;
7744 
7745     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7746     switch (encoding) {
7747     case eEncodingT1:
7748       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7749       t = Bits32(opcode, 2, 0);
7750       n = Bits32(opcode, 5, 3);
7751       m = Bits32(opcode, 8, 6);
7752 
7753       // index = TRUE; add = TRUE; wback = FALSE;
7754       index = true;
7755       add = true;
7756       wback = false;
7757 
7758       // (shift_t, shift_n) = (SRType_LSL, 0);
7759       shift_t = SRType_LSL;
7760       shift_n = 0;
7761 
7762       break;
7763 
7764     case eEncodingT2:
7765       // if Rt == '1111' then SEE PLI;
7766       // if Rn == '1111' then SEE LDRSB (literal);
7767       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7768       t = Bits32(opcode, 15, 12);
7769       n = Bits32(opcode, 19, 16);
7770       m = Bits32(opcode, 3, 0);
7771 
7772       // index = TRUE; add = TRUE; wback = FALSE;
7773       index = true;
7774       add = true;
7775       wback = false;
7776 
7777       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7778       shift_t = SRType_LSL;
7779       shift_n = Bits32(opcode, 5, 4);
7780 
7781       // if t == 13 || BadReg(m) then UNPREDICTABLE;
7782       if ((t == 13) || BadReg(m))
7783         return false;
7784       break;
7785 
7786     case eEncodingA1:
7787       // if P == '0' && W == '1' then SEE LDRSBT;
7788       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7789       t = Bits32(opcode, 15, 12);
7790       n = Bits32(opcode, 19, 16);
7791       m = Bits32(opcode, 3, 0);
7792 
7793       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7794       // (W == '1');
7795       index = BitIsSet(opcode, 24);
7796       add = BitIsSet(opcode, 23);
7797       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7798 
7799       // (shift_t, shift_n) = (SRType_LSL, 0);
7800       shift_t = SRType_LSL;
7801       shift_n = 0;
7802 
7803       // if t == 15 || m == 15 then UNPREDICTABLE;
7804       if ((t == 15) || (m == 15))
7805         return false;
7806 
7807       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7808       if (wback && ((n == 15) || (n == t)))
7809         return false;
7810       break;
7811 
7812     default:
7813       return false;
7814     }
7815 
7816     uint64_t Rm =
7817         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7818     if (!success)
7819       return false;
7820 
7821     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7822     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7823     if (!success)
7824       return false;
7825 
7826     addr_t offset_addr;
7827     addr_t address;
7828 
7829     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7830     uint64_t Rn =
7831         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7832     if (!success)
7833       return false;
7834 
7835     if (add)
7836       offset_addr = Rn + offset;
7837     else
7838       offset_addr = Rn - offset;
7839 
7840     // address = if index then offset_addr else R[n];
7841     if (index)
7842       address = offset_addr;
7843     else
7844       address = Rn;
7845 
7846     // R[t] = SignExtend(MemU[address,1], 32);
7847     std::optional<RegisterInfo> base_reg =
7848         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7849     std::optional<RegisterInfo> offset_reg =
7850         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
7851 
7852     EmulateInstruction::Context context;
7853     context.type = eContextRegisterLoad;
7854     context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7855 
7856     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7857     if (!success)
7858       return false;
7859 
7860     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7861     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7862                                (uint64_t)signed_data))
7863       return false;
7864 
7865     // if wback then R[n] = offset_addr;
7866     if (wback) {
7867       context.type = eContextAdjustBaseRegister;
7868       context.SetAddress(offset_addr);
7869       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7870                                  offset_addr))
7871         return false;
7872     }
7873   }
7874   return true;
7875 }
7876 
7877 // LDRSH (immediate) calculates an address from a base register value and an
7878 // immediate offset, loads a halfword from
7879 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7880 // It can use offset, post-indexed, or pre-indexed addressing.
7881 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7882                                                   const ARMEncoding encoding) {
7883 #if 0
7884     if ConditionPassed() then
7885         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7886         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7887         address = if index then offset_addr else R[n];
7888         data = MemU[address,2];
7889         if wback then R[n] = offset_addr;
7890         if UnalignedSupport() || address<0> = '0' then
7891             R[t] = SignExtend(data, 32);
7892         else // Can only apply before ARMv7
7893             R[t] = bits(32) UNKNOWN;
7894 #endif
7895 
7896   bool success = false;
7897 
7898   if (ConditionPassed(opcode)) {
7899     uint32_t t;
7900     uint32_t n;
7901     uint32_t imm32;
7902     bool index;
7903     bool add;
7904     bool wback;
7905 
7906     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7907     switch (encoding) {
7908     case eEncodingT1:
7909       // if Rn == '1111' then SEE LDRSH (literal);
7910       // if Rt == '1111' then SEE "Unallocated memory hints";
7911       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7912       t = Bits32(opcode, 15, 12);
7913       n = Bits32(opcode, 19, 16);
7914       imm32 = Bits32(opcode, 11, 0);
7915 
7916       // index = TRUE; add = TRUE; wback = FALSE;
7917       index = true;
7918       add = true;
7919       wback = false;
7920 
7921       // if t == 13 then UNPREDICTABLE;
7922       if (t == 13)
7923         return false;
7924 
7925       break;
7926 
7927     case eEncodingT2:
7928       // if Rn == '1111' then SEE LDRSH (literal);
7929       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7930       // "Unallocated memory hints";
7931       // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7932       // if P == '0' && W == '0' then UNDEFINED;
7933       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7934         return false;
7935 
7936       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7937       t = Bits32(opcode, 15, 12);
7938       n = Bits32(opcode, 19, 16);
7939       imm32 = Bits32(opcode, 7, 0);
7940 
7941       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7942       index = BitIsSet(opcode, 10);
7943       add = BitIsSet(opcode, 9);
7944       wback = BitIsSet(opcode, 8);
7945 
7946       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7947       if (BadReg(t) || (wback && (n == t)))
7948         return false;
7949 
7950       break;
7951 
7952     case eEncodingA1: {
7953       // if Rn == '1111' then SEE LDRSH (literal);
7954       // if P == '0' && W == '1' then SEE LDRSHT;
7955       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7956       t = Bits32(opcode, 15, 12);
7957       n = Bits32(opcode, 19, 16);
7958       uint32_t imm4H = Bits32(opcode, 11, 8);
7959       uint32_t imm4L = Bits32(opcode, 3, 0);
7960       imm32 = (imm4H << 4) | imm4L;
7961 
7962       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7963       // (W == '1');
7964       index = BitIsSet(opcode, 24);
7965       add = BitIsSet(opcode, 23);
7966       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7967 
7968       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7969       if ((t == 15) || (wback && (n == t)))
7970         return false;
7971 
7972       break;
7973     }
7974 
7975     default:
7976       return false;
7977     }
7978 
7979     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7980     uint64_t Rn =
7981         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7982     if (!success)
7983       return false;
7984 
7985     addr_t offset_addr;
7986     if (add)
7987       offset_addr = Rn + imm32;
7988     else
7989       offset_addr = Rn - imm32;
7990 
7991     // address = if index then offset_addr else R[n];
7992     addr_t address;
7993     if (index)
7994       address = offset_addr;
7995     else
7996       address = Rn;
7997 
7998     // data = MemU[address,2];
7999     std::optional<RegisterInfo> base_reg =
8000         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8001 
8002     EmulateInstruction::Context context;
8003     context.type = eContextRegisterLoad;
8004     context.SetRegisterPlusOffset(*base_reg, address - Rn);
8005 
8006     uint64_t data = MemURead(context, address, 2, 0, &success);
8007     if (!success)
8008       return false;
8009 
8010     // if wback then R[n] = offset_addr;
8011     if (wback) {
8012       context.type = eContextAdjustBaseRegister;
8013       context.SetAddress(offset_addr);
8014       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8015                                  offset_addr))
8016         return false;
8017     }
8018 
8019     // if UnalignedSupport() || address<0> = '0' then
8020     if (UnalignedSupport() || BitIsClear(address, 0)) {
8021       // R[t] = SignExtend(data, 32);
8022       int64_t signed_data = llvm::SignExtend64<16>(data);
8023       context.type = eContextRegisterLoad;
8024       context.SetRegisterPlusOffset(*base_reg, address - Rn);
8025       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8026                                  (uint64_t)signed_data))
8027         return false;
8028     } else // Can only apply before ARMv7
8029     {
8030       // R[t] = bits(32) UNKNOWN;
8031       WriteBits32Unknown(t);
8032     }
8033   }
8034   return true;
8035 }
8036 
8037 // LDRSH (literal) calculates an address from the PC value and an immediate
8038 // offset, loads a halfword from memory,
8039 // sign-extends it to from a 32-bit word, and writes it to a register.
8040 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8041                                                 const ARMEncoding encoding) {
8042 #if 0
8043     if ConditionPassed() then
8044         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8045         base = Align(PC,4);
8046         address = if add then (base + imm32) else (base - imm32);
8047         data = MemU[address,2];
8048         if UnalignedSupport() || address<0> = '0' then
8049             R[t] = SignExtend(data, 32);
8050         else // Can only apply before ARMv7
8051             R[t] = bits(32) UNKNOWN;
8052 #endif
8053 
8054   bool success = false;
8055 
8056   if (ConditionPassed(opcode)) {
8057     uint32_t t;
8058     uint32_t imm32;
8059     bool add;
8060 
8061     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8062     switch (encoding) {
8063     case eEncodingT1:
8064       // if Rt == '1111' then SEE "Unallocated memory hints";
8065       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8066       t = Bits32(opcode, 15, 12);
8067       imm32 = Bits32(opcode, 11, 0);
8068       add = BitIsSet(opcode, 23);
8069 
8070       // if t == 13 then UNPREDICTABLE;
8071       if (t == 13)
8072         return false;
8073 
8074       break;
8075 
8076     case eEncodingA1: {
8077       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8078       t = Bits32(opcode, 15, 12);
8079       uint32_t imm4H = Bits32(opcode, 11, 8);
8080       uint32_t imm4L = Bits32(opcode, 3, 0);
8081       imm32 = (imm4H << 4) | imm4L;
8082       add = BitIsSet(opcode, 23);
8083 
8084       // if t == 15 then UNPREDICTABLE;
8085       if (t == 15)
8086         return false;
8087 
8088       break;
8089     }
8090     default:
8091       return false;
8092     }
8093 
8094     // base = Align(PC,4);
8095     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8096     if (!success)
8097       return false;
8098 
8099     uint64_t base = AlignPC(pc_value);
8100 
8101     addr_t address;
8102     // address = if add then (base + imm32) else (base - imm32);
8103     if (add)
8104       address = base + imm32;
8105     else
8106       address = base - imm32;
8107 
8108     // data = MemU[address,2];
8109     std::optional<RegisterInfo> base_reg =
8110         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
8111 
8112     EmulateInstruction::Context context;
8113     context.type = eContextRegisterLoad;
8114     context.SetRegisterPlusOffset(*base_reg, imm32);
8115 
8116     uint64_t data = MemURead(context, address, 2, 0, &success);
8117     if (!success)
8118       return false;
8119 
8120     // if UnalignedSupport() || address<0> = '0' then
8121     if (UnalignedSupport() || BitIsClear(address, 0)) {
8122       // R[t] = SignExtend(data, 32);
8123       int64_t signed_data = llvm::SignExtend64<16>(data);
8124       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8125                                  (uint64_t)signed_data))
8126         return false;
8127     } else // Can only apply before ARMv7
8128     {
8129       // R[t] = bits(32) UNKNOWN;
8130       WriteBits32Unknown(t);
8131     }
8132   }
8133   return true;
8134 }
8135 
8136 // LDRSH (register) calculates an address from a base register value and an
8137 // offset register value, loads a halfword
8138 // from memory, sign-extends it to form a 32-bit word, and writes it to a
8139 // register.  The offset register value can be shifted left by 0, 1, 2, or 3
8140 // bits.
8141 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8142                                                  const ARMEncoding encoding) {
8143 #if 0
8144     if ConditionPassed() then
8145         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8146         offset = Shift(R[m], shift_t, shift_n, APSR.C);
8147         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8148         address = if index then offset_addr else R[n];
8149         data = MemU[address,2];
8150         if wback then R[n] = offset_addr;
8151         if UnalignedSupport() || address<0> = '0' then
8152             R[t] = SignExtend(data, 32);
8153         else // Can only apply before ARMv7
8154             R[t] = bits(32) UNKNOWN;
8155 #endif
8156 
8157   bool success = false;
8158 
8159   if (ConditionPassed(opcode)) {
8160     uint32_t t;
8161     uint32_t n;
8162     uint32_t m;
8163     bool index;
8164     bool add;
8165     bool wback;
8166     ARM_ShifterType shift_t;
8167     uint32_t shift_n;
8168 
8169     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8170     switch (encoding) {
8171     case eEncodingT1:
8172       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8173       // in ThumbEE";
8174       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8175       t = Bits32(opcode, 2, 0);
8176       n = Bits32(opcode, 5, 3);
8177       m = Bits32(opcode, 8, 6);
8178 
8179       // index = TRUE; add = TRUE; wback = FALSE;
8180       index = true;
8181       add = true;
8182       wback = false;
8183 
8184       // (shift_t, shift_n) = (SRType_LSL, 0);
8185       shift_t = SRType_LSL;
8186       shift_n = 0;
8187 
8188       break;
8189 
8190     case eEncodingT2:
8191       // if Rn == '1111' then SEE LDRSH (literal);
8192       // if Rt == '1111' then SEE "Unallocated memory hints";
8193       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8194       t = Bits32(opcode, 15, 12);
8195       n = Bits32(opcode, 19, 16);
8196       m = Bits32(opcode, 3, 0);
8197 
8198       // index = TRUE; add = TRUE; wback = FALSE;
8199       index = true;
8200       add = true;
8201       wback = false;
8202 
8203       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8204       shift_t = SRType_LSL;
8205       shift_n = Bits32(opcode, 5, 4);
8206 
8207       // if t == 13 || BadReg(m) then UNPREDICTABLE;
8208       if ((t == 13) || BadReg(m))
8209         return false;
8210 
8211       break;
8212 
8213     case eEncodingA1:
8214       // if P == '0' && W == '1' then SEE LDRSHT;
8215       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8216       t = Bits32(opcode, 15, 12);
8217       n = Bits32(opcode, 19, 16);
8218       m = Bits32(opcode, 3, 0);
8219 
8220       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
8221       // (W == '1');
8222       index = BitIsSet(opcode, 24);
8223       add = BitIsSet(opcode, 23);
8224       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8225 
8226       // (shift_t, shift_n) = (SRType_LSL, 0);
8227       shift_t = SRType_LSL;
8228       shift_n = 0;
8229 
8230       // if t == 15 || m == 15 then UNPREDICTABLE;
8231       if ((t == 15) || (m == 15))
8232         return false;
8233 
8234       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8235       if (wback && ((n == 15) || (n == t)))
8236         return false;
8237 
8238       break;
8239 
8240     default:
8241       return false;
8242     }
8243 
8244     uint64_t Rm =
8245         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8246     if (!success)
8247       return false;
8248 
8249     uint64_t Rn =
8250         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8251     if (!success)
8252       return false;
8253 
8254     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8255     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8256     if (!success)
8257       return false;
8258 
8259     addr_t offset_addr;
8260     addr_t address;
8261 
8262     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8263     if (add)
8264       offset_addr = Rn + offset;
8265     else
8266       offset_addr = Rn - offset;
8267 
8268     // address = if index then offset_addr else R[n];
8269     if (index)
8270       address = offset_addr;
8271     else
8272       address = Rn;
8273 
8274     // data = MemU[address,2];
8275     std::optional<RegisterInfo> base_reg =
8276         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8277     std::optional<RegisterInfo> offset_reg =
8278         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8279 
8280     EmulateInstruction::Context context;
8281     context.type = eContextRegisterLoad;
8282     context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
8283 
8284     uint64_t data = MemURead(context, address, 2, 0, &success);
8285     if (!success)
8286       return false;
8287 
8288     // if wback then R[n] = offset_addr;
8289     if (wback) {
8290       context.type = eContextAdjustBaseRegister;
8291       context.SetAddress(offset_addr);
8292       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8293                                  offset_addr))
8294         return false;
8295     }
8296 
8297     // if UnalignedSupport() || address<0> = '0' then
8298     if (UnalignedSupport() || BitIsClear(address, 0)) {
8299       // R[t] = SignExtend(data, 32);
8300       context.type = eContextRegisterLoad;
8301       context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
8302 
8303       int64_t signed_data = llvm::SignExtend64<16>(data);
8304       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8305                                  (uint64_t)signed_data))
8306         return false;
8307     } else // Can only apply before ARMv7
8308     {
8309       // R[t] = bits(32) UNKNOWN;
8310       WriteBits32Unknown(t);
8311     }
8312   }
8313   return true;
8314 }
8315 
8316 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8317 // writes the result to the destination
8318 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8319 // extracting the 8-bit value.
8320 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8321                                         const ARMEncoding encoding) {
8322 #if 0
8323     if ConditionPassed() then
8324         EncodingSpecificOperations();
8325         rotated = ROR(R[m], rotation);
8326         R[d] = SignExtend(rotated<7:0>, 32);
8327 #endif
8328 
8329   bool success = false;
8330 
8331   if (ConditionPassed(opcode)) {
8332     uint32_t d;
8333     uint32_t m;
8334     uint32_t rotation;
8335 
8336     // EncodingSpecificOperations();
8337     switch (encoding) {
8338     case eEncodingT1:
8339       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8340       d = Bits32(opcode, 2, 0);
8341       m = Bits32(opcode, 5, 3);
8342       rotation = 0;
8343 
8344       break;
8345 
8346     case eEncodingT2:
8347       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8348       d = Bits32(opcode, 11, 8);
8349       m = Bits32(opcode, 3, 0);
8350       rotation = Bits32(opcode, 5, 4) << 3;
8351 
8352       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8353       if (BadReg(d) || BadReg(m))
8354         return false;
8355 
8356       break;
8357 
8358     case eEncodingA1:
8359       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8360       d = Bits32(opcode, 15, 12);
8361       m = Bits32(opcode, 3, 0);
8362       rotation = Bits32(opcode, 11, 10) << 3;
8363 
8364       // if d == 15 || m == 15 then UNPREDICTABLE;
8365       if ((d == 15) || (m == 15))
8366         return false;
8367 
8368       break;
8369 
8370     default:
8371       return false;
8372     }
8373 
8374     uint64_t Rm =
8375         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8376     if (!success)
8377       return false;
8378 
8379     // rotated = ROR(R[m], rotation);
8380     uint64_t rotated = ROR(Rm, rotation, &success);
8381     if (!success)
8382       return false;
8383 
8384     // R[d] = SignExtend(rotated<7:0>, 32);
8385     int64_t data = llvm::SignExtend64<8>(rotated);
8386 
8387     std::optional<RegisterInfo> source_reg =
8388         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8389 
8390     EmulateInstruction::Context context;
8391     context.type = eContextRegisterLoad;
8392     context.SetRegister(*source_reg);
8393 
8394     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8395                                (uint64_t)data))
8396       return false;
8397   }
8398   return true;
8399 }
8400 
8401 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8402 // writes the result to the destination
8403 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8404 // extracting the 16-bit value.
8405 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8406                                         const ARMEncoding encoding) {
8407 #if 0
8408     if ConditionPassed() then
8409         EncodingSpecificOperations();
8410         rotated = ROR(R[m], rotation);
8411         R[d] = SignExtend(rotated<15:0>, 32);
8412 #endif
8413 
8414   bool success = false;
8415 
8416   if (ConditionPassed(opcode)) {
8417     uint32_t d;
8418     uint32_t m;
8419     uint32_t rotation;
8420 
8421     // EncodingSpecificOperations();
8422     switch (encoding) {
8423     case eEncodingT1:
8424       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8425       d = Bits32(opcode, 2, 0);
8426       m = Bits32(opcode, 5, 3);
8427       rotation = 0;
8428 
8429       break;
8430 
8431     case eEncodingT2:
8432       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8433       d = Bits32(opcode, 11, 8);
8434       m = Bits32(opcode, 3, 0);
8435       rotation = Bits32(opcode, 5, 4) << 3;
8436 
8437       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8438       if (BadReg(d) || BadReg(m))
8439         return false;
8440 
8441       break;
8442 
8443     case eEncodingA1:
8444       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8445       d = Bits32(opcode, 15, 12);
8446       m = Bits32(opcode, 3, 0);
8447       rotation = Bits32(opcode, 11, 10) << 3;
8448 
8449       // if d == 15 || m == 15 then UNPREDICTABLE;
8450       if ((d == 15) || (m == 15))
8451         return false;
8452 
8453       break;
8454 
8455     default:
8456       return false;
8457     }
8458 
8459     uint64_t Rm =
8460         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8461     if (!success)
8462       return false;
8463 
8464     // rotated = ROR(R[m], rotation);
8465     uint64_t rotated = ROR(Rm, rotation, &success);
8466     if (!success)
8467       return false;
8468 
8469     // R[d] = SignExtend(rotated<15:0>, 32);
8470     std::optional<RegisterInfo> source_reg =
8471         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8472 
8473     EmulateInstruction::Context context;
8474     context.type = eContextRegisterLoad;
8475     context.SetRegister(*source_reg);
8476 
8477     int64_t data = llvm::SignExtend64<16>(rotated);
8478     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8479                                (uint64_t)data))
8480       return false;
8481   }
8482 
8483   return true;
8484 }
8485 
8486 // UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and
8487 // writes the result to the destination
8488 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8489 // extracting the 8-bit value.
8490 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8491                                         const ARMEncoding encoding) {
8492 #if 0
8493     if ConditionPassed() then
8494         EncodingSpecificOperations();
8495         rotated = ROR(R[m], rotation);
8496         R[d] = ZeroExtend(rotated<7:0>, 32);
8497 #endif
8498 
8499   bool success = false;
8500 
8501   if (ConditionPassed(opcode)) {
8502     uint32_t d;
8503     uint32_t m;
8504     uint32_t rotation;
8505 
8506     // EncodingSpecificOperations();
8507     switch (encoding) {
8508     case eEncodingT1:
8509       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8510       d = Bits32(opcode, 2, 0);
8511       m = Bits32(opcode, 5, 3);
8512       rotation = 0;
8513 
8514       break;
8515 
8516     case eEncodingT2:
8517       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8518       d = Bits32(opcode, 11, 8);
8519       m = Bits32(opcode, 3, 0);
8520       rotation = Bits32(opcode, 5, 4) << 3;
8521 
8522       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8523       if (BadReg(d) || BadReg(m))
8524         return false;
8525 
8526       break;
8527 
8528     case eEncodingA1:
8529       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8530       d = Bits32(opcode, 15, 12);
8531       m = Bits32(opcode, 3, 0);
8532       rotation = Bits32(opcode, 11, 10) << 3;
8533 
8534       // if d == 15 || m == 15 then UNPREDICTABLE;
8535       if ((d == 15) || (m == 15))
8536         return false;
8537 
8538       break;
8539 
8540     default:
8541       return false;
8542     }
8543 
8544     uint64_t Rm =
8545         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8546     if (!success)
8547       return false;
8548 
8549     // rotated = ROR(R[m], rotation);
8550     uint64_t rotated = ROR(Rm, rotation, &success);
8551     if (!success)
8552       return false;
8553 
8554     // R[d] = ZeroExtend(rotated<7:0>, 32);
8555     std::optional<RegisterInfo> source_reg =
8556         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8557 
8558     EmulateInstruction::Context context;
8559     context.type = eContextRegisterLoad;
8560     context.SetRegister(*source_reg);
8561 
8562     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8563                                Bits32(rotated, 7, 0)))
8564       return false;
8565   }
8566   return true;
8567 }
8568 
8569 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8570 // writes the result to the destination
8571 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8572 // extracting the 16-bit value.
8573 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8574                                         const ARMEncoding encoding) {
8575 #if 0
8576     if ConditionPassed() then
8577         EncodingSpecificOperations();
8578         rotated = ROR(R[m], rotation);
8579         R[d] = ZeroExtend(rotated<15:0>, 32);
8580 #endif
8581 
8582   bool success = false;
8583 
8584   if (ConditionPassed(opcode)) {
8585     uint32_t d;
8586     uint32_t m;
8587     uint32_t rotation;
8588 
8589     switch (encoding) {
8590     case eEncodingT1:
8591       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8592       d = Bits32(opcode, 2, 0);
8593       m = Bits32(opcode, 5, 3);
8594       rotation = 0;
8595 
8596       break;
8597 
8598     case eEncodingT2:
8599       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8600       d = Bits32(opcode, 11, 8);
8601       m = Bits32(opcode, 3, 0);
8602       rotation = Bits32(opcode, 5, 4) << 3;
8603 
8604       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8605       if (BadReg(d) || BadReg(m))
8606         return false;
8607 
8608       break;
8609 
8610     case eEncodingA1:
8611       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8612       d = Bits32(opcode, 15, 12);
8613       m = Bits32(opcode, 3, 0);
8614       rotation = Bits32(opcode, 11, 10) << 3;
8615 
8616       // if d == 15 || m == 15 then UNPREDICTABLE;
8617       if ((d == 15) || (m == 15))
8618         return false;
8619 
8620       break;
8621 
8622     default:
8623       return false;
8624     }
8625 
8626     uint64_t Rm =
8627         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8628     if (!success)
8629       return false;
8630 
8631     // rotated = ROR(R[m], rotation);
8632     uint64_t rotated = ROR(Rm, rotation, &success);
8633     if (!success)
8634       return false;
8635 
8636     // R[d] = ZeroExtend(rotated<15:0>, 32);
8637     std::optional<RegisterInfo> source_reg =
8638         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8639 
8640     EmulateInstruction::Context context;
8641     context.type = eContextRegisterLoad;
8642     context.SetRegister(*source_reg);
8643 
8644     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8645                                Bits32(rotated, 15, 0)))
8646       return false;
8647   }
8648   return true;
8649 }
8650 
8651 // RFE (Return From Exception) loads the PC and the CPSR from the word at the
8652 // specified address and the following
8653 // word respectively.
8654 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8655                                        const ARMEncoding encoding) {
8656 #if 0
8657     if ConditionPassed() then
8658         EncodingSpecificOperations();
8659         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8660             UNPREDICTABLE;
8661         else
8662             address = if increment then R[n] else R[n]-8;
8663             if wordhigher then address = address+4;
8664             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8665             BranchWritePC(MemA[address,4]);
8666             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8667 #endif
8668 
8669   bool success = false;
8670 
8671   if (ConditionPassed(opcode)) {
8672     uint32_t n;
8673     bool wback;
8674     bool increment;
8675     bool wordhigher;
8676 
8677     // EncodingSpecificOperations();
8678     switch (encoding) {
8679     case eEncodingT1:
8680       // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8681       // FALSE;
8682       n = Bits32(opcode, 19, 16);
8683       wback = BitIsSet(opcode, 21);
8684       increment = false;
8685       wordhigher = false;
8686 
8687       // if n == 15 then UNPREDICTABLE;
8688       if (n == 15)
8689         return false;
8690 
8691       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8692       if (InITBlock() && !LastInITBlock())
8693         return false;
8694 
8695       break;
8696 
8697     case eEncodingT2:
8698       // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8699       n = Bits32(opcode, 19, 16);
8700       wback = BitIsSet(opcode, 21);
8701       increment = true;
8702       wordhigher = false;
8703 
8704       // if n == 15 then UNPREDICTABLE;
8705       if (n == 15)
8706         return false;
8707 
8708       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8709       if (InITBlock() && !LastInITBlock())
8710         return false;
8711 
8712       break;
8713 
8714     case eEncodingA1:
8715       // n = UInt(Rn);
8716       n = Bits32(opcode, 19, 16);
8717 
8718       // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8719       wback = BitIsSet(opcode, 21);
8720       increment = BitIsSet(opcode, 23);
8721       wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8722 
8723       // if n == 15 then UNPREDICTABLE;
8724       if (n == 15)
8725         return false;
8726 
8727       break;
8728 
8729     default:
8730       return false;
8731     }
8732 
8733     // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8734     // then
8735     if (!CurrentModeIsPrivileged())
8736       // UNPREDICTABLE;
8737       return false;
8738     else {
8739       uint64_t Rn =
8740           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8741       if (!success)
8742         return false;
8743 
8744       addr_t address;
8745       // address = if increment then R[n] else R[n]-8;
8746       if (increment)
8747         address = Rn;
8748       else
8749         address = Rn - 8;
8750 
8751       // if wordhigher then address = address+4;
8752       if (wordhigher)
8753         address = address + 4;
8754 
8755       // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8756       std::optional<RegisterInfo> base_reg =
8757           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8758 
8759       EmulateInstruction::Context context;
8760       context.type = eContextReturnFromException;
8761       context.SetRegisterPlusOffset(*base_reg, address - Rn);
8762 
8763       uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8764       if (!success)
8765         return false;
8766 
8767       CPSRWriteByInstr(data, 15, true);
8768 
8769       // BranchWritePC(MemA[address,4]);
8770       uint64_t data2 = MemARead(context, address, 4, 0, &success);
8771       if (!success)
8772         return false;
8773 
8774       BranchWritePC(context, data2);
8775 
8776       // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8777       if (wback) {
8778         context.type = eContextAdjustBaseRegister;
8779         if (increment) {
8780           context.SetOffset(8);
8781           if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8782                                      Rn + 8))
8783             return false;
8784         } else {
8785           context.SetOffset(-8);
8786           if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8787                                      Rn - 8))
8788             return false;
8789         }
8790       } // if wback
8791     }
8792   } // if ConditionPassed()
8793   return true;
8794 }
8795 
8796 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8797 // register value and an immediate value, and writes the result to the
8798 // destination register.  It can optionally update the condition flags based on
8799 // the result.
8800 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8801                                           const ARMEncoding encoding) {
8802 #if 0
8803     // ARM pseudo code...
8804     if ConditionPassed() then
8805         EncodingSpecificOperations();
8806         result = R[n] EOR imm32;
8807         if d == 15 then         // Can only occur for ARM encoding
8808             ALUWritePC(result); // setflags is always FALSE here
8809         else
8810             R[d] = result;
8811             if setflags then
8812                 APSR.N = result<31>;
8813                 APSR.Z = IsZeroBit(result);
8814                 APSR.C = carry;
8815                 // APSR.V unchanged
8816 #endif
8817 
8818   bool success = false;
8819 
8820   if (ConditionPassed(opcode)) {
8821     uint32_t Rd, Rn;
8822     uint32_t
8823         imm32; // the immediate value to be ORed to the value obtained from Rn
8824     bool setflags;
8825     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8826     switch (encoding) {
8827     case eEncodingT1:
8828       Rd = Bits32(opcode, 11, 8);
8829       Rn = Bits32(opcode, 19, 16);
8830       setflags = BitIsSet(opcode, 20);
8831       imm32 = ThumbExpandImm_C(
8832           opcode, APSR_C,
8833           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8834       // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8835       if (Rd == 15 && setflags)
8836         return EmulateTEQImm(opcode, eEncodingT1);
8837       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8838         return false;
8839       break;
8840     case eEncodingA1:
8841       Rd = Bits32(opcode, 15, 12);
8842       Rn = Bits32(opcode, 19, 16);
8843       setflags = BitIsSet(opcode, 20);
8844       imm32 =
8845           ARMExpandImm_C(opcode, APSR_C,
8846                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8847 
8848       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8849       // instructions;
8850       if (Rd == 15 && setflags)
8851         return EmulateSUBSPcLrEtc(opcode, encoding);
8852       break;
8853     default:
8854       return false;
8855     }
8856 
8857     // Read the first operand.
8858     uint32_t val1 = ReadCoreReg(Rn, &success);
8859     if (!success)
8860       return false;
8861 
8862     uint32_t result = val1 ^ imm32;
8863 
8864     EmulateInstruction::Context context;
8865     context.type = EmulateInstruction::eContextImmediate;
8866     context.SetNoArgs();
8867 
8868     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8869       return false;
8870   }
8871   return true;
8872 }
8873 
8874 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8875 // register value and an optionally-shifted register value, and writes the
8876 // result to the destination register. It can optionally update the condition
8877 // flags based on the result.
8878 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8879                                           const ARMEncoding encoding) {
8880 #if 0
8881     // ARM pseudo code...
8882     if ConditionPassed() then
8883         EncodingSpecificOperations();
8884         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8885         result = R[n] EOR shifted;
8886         if d == 15 then         // Can only occur for ARM encoding
8887             ALUWritePC(result); // setflags is always FALSE here
8888         else
8889             R[d] = result;
8890             if setflags then
8891                 APSR.N = result<31>;
8892                 APSR.Z = IsZeroBit(result);
8893                 APSR.C = carry;
8894                 // APSR.V unchanged
8895 #endif
8896 
8897   bool success = false;
8898 
8899   if (ConditionPassed(opcode)) {
8900     uint32_t Rd, Rn, Rm;
8901     ARM_ShifterType shift_t;
8902     uint32_t shift_n; // the shift applied to the value read from Rm
8903     bool setflags;
8904     uint32_t carry;
8905     switch (encoding) {
8906     case eEncodingT1:
8907       Rd = Rn = Bits32(opcode, 2, 0);
8908       Rm = Bits32(opcode, 5, 3);
8909       setflags = !InITBlock();
8910       shift_t = SRType_LSL;
8911       shift_n = 0;
8912       break;
8913     case eEncodingT2:
8914       Rd = Bits32(opcode, 11, 8);
8915       Rn = Bits32(opcode, 19, 16);
8916       Rm = Bits32(opcode, 3, 0);
8917       setflags = BitIsSet(opcode, 20);
8918       shift_n = DecodeImmShiftThumb(opcode, shift_t);
8919       // if Rd == '1111' && S == '1' then SEE TEQ (register);
8920       if (Rd == 15 && setflags)
8921         return EmulateTEQReg(opcode, eEncodingT1);
8922       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8923         return false;
8924       break;
8925     case eEncodingA1:
8926       Rd = Bits32(opcode, 15, 12);
8927       Rn = Bits32(opcode, 19, 16);
8928       Rm = Bits32(opcode, 3, 0);
8929       setflags = BitIsSet(opcode, 20);
8930       shift_n = DecodeImmShiftARM(opcode, shift_t);
8931 
8932       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8933       // instructions;
8934       if (Rd == 15 && setflags)
8935         return EmulateSUBSPcLrEtc(opcode, encoding);
8936       break;
8937     default:
8938       return false;
8939     }
8940 
8941     // Read the first operand.
8942     uint32_t val1 = ReadCoreReg(Rn, &success);
8943     if (!success)
8944       return false;
8945 
8946     // Read the second operand.
8947     uint32_t val2 = ReadCoreReg(Rm, &success);
8948     if (!success)
8949       return false;
8950 
8951     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8952     if (!success)
8953       return false;
8954     uint32_t result = val1 ^ shifted;
8955 
8956     EmulateInstruction::Context context;
8957     context.type = EmulateInstruction::eContextImmediate;
8958     context.SetNoArgs();
8959 
8960     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8961       return false;
8962   }
8963   return true;
8964 }
8965 
8966 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8967 // and an immediate value, and writes the result to the destination register.
8968 // It can optionally update the condition flags based on the result.
8969 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8970                                           const ARMEncoding encoding) {
8971 #if 0
8972     // ARM pseudo code...
8973     if ConditionPassed() then
8974         EncodingSpecificOperations();
8975         result = R[n] OR imm32;
8976         if d == 15 then         // Can only occur for ARM encoding
8977             ALUWritePC(result); // setflags is always FALSE here
8978         else
8979             R[d] = result;
8980             if setflags then
8981                 APSR.N = result<31>;
8982                 APSR.Z = IsZeroBit(result);
8983                 APSR.C = carry;
8984                 // APSR.V unchanged
8985 #endif
8986 
8987   bool success = false;
8988 
8989   if (ConditionPassed(opcode)) {
8990     uint32_t Rd, Rn;
8991     uint32_t
8992         imm32; // the immediate value to be ORed to the value obtained from Rn
8993     bool setflags;
8994     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8995     switch (encoding) {
8996     case eEncodingT1:
8997       Rd = Bits32(opcode, 11, 8);
8998       Rn = Bits32(opcode, 19, 16);
8999       setflags = BitIsSet(opcode, 20);
9000       imm32 = ThumbExpandImm_C(
9001           opcode, APSR_C,
9002           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9003       // if Rn == '1111' then SEE MOV (immediate);
9004       if (Rn == 15)
9005         return EmulateMOVRdImm(opcode, eEncodingT2);
9006       if (BadReg(Rd) || Rn == 13)
9007         return false;
9008       break;
9009     case eEncodingA1:
9010       Rd = Bits32(opcode, 15, 12);
9011       Rn = Bits32(opcode, 19, 16);
9012       setflags = BitIsSet(opcode, 20);
9013       imm32 =
9014           ARMExpandImm_C(opcode, APSR_C,
9015                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9016 
9017       if (Rd == 15 && setflags)
9018         return EmulateSUBSPcLrEtc(opcode, encoding);
9019       break;
9020     default:
9021       return false;
9022     }
9023 
9024     // Read the first operand.
9025     uint32_t val1 = ReadCoreReg(Rn, &success);
9026     if (!success)
9027       return false;
9028 
9029     uint32_t result = val1 | imm32;
9030 
9031     EmulateInstruction::Context context;
9032     context.type = EmulateInstruction::eContextImmediate;
9033     context.SetNoArgs();
9034 
9035     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9036       return false;
9037   }
9038   return true;
9039 }
9040 
9041 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9042 // and an optionally-shifted register value, and writes the result to the
9043 // destination register.  It can optionally update the condition flags based on
9044 // the result.
9045 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9046                                           const ARMEncoding encoding) {
9047 #if 0
9048     // ARM pseudo code...
9049     if ConditionPassed() then
9050         EncodingSpecificOperations();
9051         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9052         result = R[n] OR shifted;
9053         if d == 15 then         // Can only occur for ARM encoding
9054             ALUWritePC(result); // setflags is always FALSE here
9055         else
9056             R[d] = result;
9057             if setflags then
9058                 APSR.N = result<31>;
9059                 APSR.Z = IsZeroBit(result);
9060                 APSR.C = carry;
9061                 // APSR.V unchanged
9062 #endif
9063 
9064   bool success = false;
9065 
9066   if (ConditionPassed(opcode)) {
9067     uint32_t Rd, Rn, Rm;
9068     ARM_ShifterType shift_t;
9069     uint32_t shift_n; // the shift applied to the value read from Rm
9070     bool setflags;
9071     uint32_t carry;
9072     switch (encoding) {
9073     case eEncodingT1:
9074       Rd = Rn = Bits32(opcode, 2, 0);
9075       Rm = Bits32(opcode, 5, 3);
9076       setflags = !InITBlock();
9077       shift_t = SRType_LSL;
9078       shift_n = 0;
9079       break;
9080     case eEncodingT2:
9081       Rd = Bits32(opcode, 11, 8);
9082       Rn = Bits32(opcode, 19, 16);
9083       Rm = Bits32(opcode, 3, 0);
9084       setflags = BitIsSet(opcode, 20);
9085       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9086       // if Rn == '1111' then SEE MOV (register);
9087       if (Rn == 15)
9088         return EmulateMOVRdRm(opcode, eEncodingT3);
9089       if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9090         return false;
9091       break;
9092     case eEncodingA1:
9093       Rd = Bits32(opcode, 15, 12);
9094       Rn = Bits32(opcode, 19, 16);
9095       Rm = Bits32(opcode, 3, 0);
9096       setflags = BitIsSet(opcode, 20);
9097       shift_n = DecodeImmShiftARM(opcode, shift_t);
9098 
9099       if (Rd == 15 && setflags)
9100         return EmulateSUBSPcLrEtc(opcode, encoding);
9101       break;
9102     default:
9103       return false;
9104     }
9105 
9106     // Read the first operand.
9107     uint32_t val1 = ReadCoreReg(Rn, &success);
9108     if (!success)
9109       return false;
9110 
9111     // Read the second operand.
9112     uint32_t val2 = ReadCoreReg(Rm, &success);
9113     if (!success)
9114       return false;
9115 
9116     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9117     if (!success)
9118       return false;
9119     uint32_t result = val1 | shifted;
9120 
9121     EmulateInstruction::Context context;
9122     context.type = EmulateInstruction::eContextImmediate;
9123     context.SetNoArgs();
9124 
9125     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9126       return false;
9127   }
9128   return true;
9129 }
9130 
9131 // Reverse Subtract (immediate) subtracts a register value from an immediate
9132 // value, and writes the result to the destination register. It can optionally
9133 // update the condition flags based on the result.
9134 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9135                                           const ARMEncoding encoding) {
9136 #if 0
9137     // ARM pseudo code...
9138     if ConditionPassed() then
9139         EncodingSpecificOperations();
9140         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9141         if d == 15 then         // Can only occur for ARM encoding
9142             ALUWritePC(result); // setflags is always FALSE here
9143         else
9144             R[d] = result;
9145             if setflags then
9146                 APSR.N = result<31>;
9147                 APSR.Z = IsZeroBit(result);
9148                 APSR.C = carry;
9149                 APSR.V = overflow;
9150 #endif
9151 
9152   bool success = false;
9153 
9154   uint32_t Rd; // the destination register
9155   uint32_t Rn; // the first operand
9156   bool setflags;
9157   uint32_t
9158       imm32; // the immediate value to be added to the value obtained from Rn
9159   switch (encoding) {
9160   case eEncodingT1:
9161     Rd = Bits32(opcode, 2, 0);
9162     Rn = Bits32(opcode, 5, 3);
9163     setflags = !InITBlock();
9164     imm32 = 0;
9165     break;
9166   case eEncodingT2:
9167     Rd = Bits32(opcode, 11, 8);
9168     Rn = Bits32(opcode, 19, 16);
9169     setflags = BitIsSet(opcode, 20);
9170     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9171     if (BadReg(Rd) || BadReg(Rn))
9172       return false;
9173     break;
9174   case eEncodingA1:
9175     Rd = Bits32(opcode, 15, 12);
9176     Rn = Bits32(opcode, 19, 16);
9177     setflags = BitIsSet(opcode, 20);
9178     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9179 
9180     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9181     // instructions;
9182     if (Rd == 15 && setflags)
9183       return EmulateSUBSPcLrEtc(opcode, encoding);
9184     break;
9185   default:
9186     return false;
9187   }
9188   // Read the register value from the operand register Rn.
9189   uint32_t reg_val = ReadCoreReg(Rn, &success);
9190   if (!success)
9191     return false;
9192 
9193   AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9194 
9195   EmulateInstruction::Context context;
9196   context.type = EmulateInstruction::eContextImmediate;
9197   context.SetNoArgs();
9198 
9199   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9200                                    res.carry_out, res.overflow);
9201 }
9202 
9203 // Reverse Subtract (register) subtracts a register value from an optionally-
9204 // shifted register value, and writes the result to the destination register.
9205 // It can optionally update the condition flags based on the result.
9206 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9207                                           const ARMEncoding encoding) {
9208 #if 0
9209     // ARM pseudo code...
9210     if ConditionPassed() then
9211         EncodingSpecificOperations();
9212         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9213         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9214         if d == 15 then         // Can only occur for ARM encoding
9215             ALUWritePC(result); // setflags is always FALSE here
9216         else
9217             R[d] = result;
9218             if setflags then
9219                 APSR.N = result<31>;
9220                 APSR.Z = IsZeroBit(result);
9221                 APSR.C = carry;
9222                 APSR.V = overflow;
9223 #endif
9224 
9225   bool success = false;
9226 
9227   uint32_t Rd; // the destination register
9228   uint32_t Rn; // the first operand
9229   uint32_t Rm; // the second operand
9230   bool setflags;
9231   ARM_ShifterType shift_t;
9232   uint32_t shift_n; // the shift applied to the value read from Rm
9233   switch (encoding) {
9234   case eEncodingT1:
9235     Rd = Bits32(opcode, 11, 8);
9236     Rn = Bits32(opcode, 19, 16);
9237     Rm = Bits32(opcode, 3, 0);
9238     setflags = BitIsSet(opcode, 20);
9239     shift_n = DecodeImmShiftThumb(opcode, shift_t);
9240     // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9241     if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9242       return false;
9243     break;
9244   case eEncodingA1:
9245     Rd = Bits32(opcode, 15, 12);
9246     Rn = Bits32(opcode, 19, 16);
9247     Rm = Bits32(opcode, 3, 0);
9248     setflags = BitIsSet(opcode, 20);
9249     shift_n = DecodeImmShiftARM(opcode, shift_t);
9250 
9251     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9252     // instructions;
9253     if (Rd == 15 && setflags)
9254       return EmulateSUBSPcLrEtc(opcode, encoding);
9255     break;
9256   default:
9257     return false;
9258   }
9259   // Read the register value from register Rn.
9260   uint32_t val1 = ReadCoreReg(Rn, &success);
9261   if (!success)
9262     return false;
9263 
9264   // Read the register value from register Rm.
9265   uint32_t val2 = ReadCoreReg(Rm, &success);
9266   if (!success)
9267     return false;
9268 
9269   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9270   if (!success)
9271     return false;
9272   AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9273 
9274   EmulateInstruction::Context context;
9275   context.type = EmulateInstruction::eContextImmediate;
9276   context.SetNoArgs();
9277   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9278                                    res.carry_out, res.overflow);
9279 }
9280 
9281 // Reverse Subtract with Carry (immediate) subtracts a register value and the
9282 // value of NOT (Carry flag) from an immediate value, and writes the result to
9283 // the destination register. It can optionally update the condition flags based
9284 // on the result.
9285 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9286                                           const ARMEncoding encoding) {
9287 #if 0
9288     // ARM pseudo code...
9289     if ConditionPassed() then
9290         EncodingSpecificOperations();
9291         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9292         if d == 15 then
9293             ALUWritePC(result); // setflags is always FALSE here
9294         else
9295             R[d] = result;
9296             if setflags then
9297                 APSR.N = result<31>;
9298                 APSR.Z = IsZeroBit(result);
9299                 APSR.C = carry;
9300                 APSR.V = overflow;
9301 #endif
9302 
9303   bool success = false;
9304 
9305   uint32_t Rd; // the destination register
9306   uint32_t Rn; // the first operand
9307   bool setflags;
9308   uint32_t
9309       imm32; // the immediate value to be added to the value obtained from Rn
9310   switch (encoding) {
9311   case eEncodingA1:
9312     Rd = Bits32(opcode, 15, 12);
9313     Rn = Bits32(opcode, 19, 16);
9314     setflags = BitIsSet(opcode, 20);
9315     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9316 
9317     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9318     // instructions;
9319     if (Rd == 15 && setflags)
9320       return EmulateSUBSPcLrEtc(opcode, encoding);
9321     break;
9322   default:
9323     return false;
9324   }
9325   // Read the register value from the operand register Rn.
9326   uint32_t reg_val = ReadCoreReg(Rn, &success);
9327   if (!success)
9328     return false;
9329 
9330   AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9331 
9332   EmulateInstruction::Context context;
9333   context.type = EmulateInstruction::eContextImmediate;
9334   context.SetNoArgs();
9335 
9336   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9337                                    res.carry_out, res.overflow);
9338 }
9339 
9340 // Reverse Subtract with Carry (register) subtracts a register value and the
9341 // value of NOT (Carry flag) from an optionally-shifted register value, and
9342 // writes the result to the destination register. It can optionally update the
9343 // condition flags based on the result.
9344 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9345                                           const ARMEncoding encoding) {
9346 #if 0
9347     // ARM pseudo code...
9348     if ConditionPassed() then
9349         EncodingSpecificOperations();
9350         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9351         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9352         if d == 15 then
9353             ALUWritePC(result); // setflags is always FALSE here
9354         else
9355             R[d] = result;
9356             if setflags then
9357                 APSR.N = result<31>;
9358                 APSR.Z = IsZeroBit(result);
9359                 APSR.C = carry;
9360                 APSR.V = overflow;
9361 #endif
9362 
9363   bool success = false;
9364 
9365   uint32_t Rd; // the destination register
9366   uint32_t Rn; // the first operand
9367   uint32_t Rm; // the second operand
9368   bool setflags;
9369   ARM_ShifterType shift_t;
9370   uint32_t shift_n; // the shift applied to the value read from Rm
9371   switch (encoding) {
9372   case eEncodingA1:
9373     Rd = Bits32(opcode, 15, 12);
9374     Rn = Bits32(opcode, 19, 16);
9375     Rm = Bits32(opcode, 3, 0);
9376     setflags = BitIsSet(opcode, 20);
9377     shift_n = DecodeImmShiftARM(opcode, shift_t);
9378 
9379     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9380     // instructions;
9381     if (Rd == 15 && setflags)
9382       return EmulateSUBSPcLrEtc(opcode, encoding);
9383     break;
9384   default:
9385     return false;
9386   }
9387   // Read the register value from register Rn.
9388   uint32_t val1 = ReadCoreReg(Rn, &success);
9389   if (!success)
9390     return false;
9391 
9392   // Read the register value from register Rm.
9393   uint32_t val2 = ReadCoreReg(Rm, &success);
9394   if (!success)
9395     return false;
9396 
9397   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9398   if (!success)
9399     return false;
9400   AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9401 
9402   EmulateInstruction::Context context;
9403   context.type = EmulateInstruction::eContextImmediate;
9404   context.SetNoArgs();
9405   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9406                                    res.carry_out, res.overflow);
9407 }
9408 
9409 // Subtract with Carry (immediate) subtracts an immediate value and the value
9410 // of
9411 // NOT (Carry flag) from a register value, and writes the result to the
9412 // destination register.
9413 // It can optionally update the condition flags based on the result.
9414 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9415                                           const ARMEncoding encoding) {
9416 #if 0
9417     // ARM pseudo code...
9418     if ConditionPassed() then
9419         EncodingSpecificOperations();
9420         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9421         if d == 15 then         // Can only occur for ARM encoding
9422             ALUWritePC(result); // setflags is always FALSE here
9423         else
9424             R[d] = result;
9425             if setflags then
9426                 APSR.N = result<31>;
9427                 APSR.Z = IsZeroBit(result);
9428                 APSR.C = carry;
9429                 APSR.V = overflow;
9430 #endif
9431 
9432   bool success = false;
9433 
9434   uint32_t Rd; // the destination register
9435   uint32_t Rn; // the first operand
9436   bool setflags;
9437   uint32_t
9438       imm32; // the immediate value to be added to the value obtained from Rn
9439   switch (encoding) {
9440   case eEncodingT1:
9441     Rd = Bits32(opcode, 11, 8);
9442     Rn = Bits32(opcode, 19, 16);
9443     setflags = BitIsSet(opcode, 20);
9444     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9445     if (BadReg(Rd) || BadReg(Rn))
9446       return false;
9447     break;
9448   case eEncodingA1:
9449     Rd = Bits32(opcode, 15, 12);
9450     Rn = Bits32(opcode, 19, 16);
9451     setflags = BitIsSet(opcode, 20);
9452     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9453 
9454     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9455     // instructions;
9456     if (Rd == 15 && setflags)
9457       return EmulateSUBSPcLrEtc(opcode, encoding);
9458     break;
9459   default:
9460     return false;
9461   }
9462   // Read the register value from the operand register Rn.
9463   uint32_t reg_val = ReadCoreReg(Rn, &success);
9464   if (!success)
9465     return false;
9466 
9467   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9468 
9469   EmulateInstruction::Context context;
9470   context.type = EmulateInstruction::eContextImmediate;
9471   context.SetNoArgs();
9472 
9473   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9474                                    res.carry_out, res.overflow);
9475 }
9476 
9477 // Subtract with Carry (register) subtracts an optionally-shifted register
9478 // value and the value of
9479 // NOT (Carry flag) from a register value, and writes the result to the
9480 // destination register.
9481 // It can optionally update the condition flags based on the result.
9482 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9483                                           const ARMEncoding encoding) {
9484 #if 0
9485     // ARM pseudo code...
9486     if ConditionPassed() then
9487         EncodingSpecificOperations();
9488         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9489         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9490         if d == 15 then         // Can only occur for ARM encoding
9491             ALUWritePC(result); // setflags is always FALSE here
9492         else
9493             R[d] = result;
9494             if setflags then
9495                 APSR.N = result<31>;
9496                 APSR.Z = IsZeroBit(result);
9497                 APSR.C = carry;
9498                 APSR.V = overflow;
9499 #endif
9500 
9501   bool success = false;
9502 
9503   uint32_t Rd; // the destination register
9504   uint32_t Rn; // the first operand
9505   uint32_t Rm; // the second operand
9506   bool setflags;
9507   ARM_ShifterType shift_t;
9508   uint32_t shift_n; // the shift applied to the value read from Rm
9509   switch (encoding) {
9510   case eEncodingT1:
9511     Rd = Rn = Bits32(opcode, 2, 0);
9512     Rm = Bits32(opcode, 5, 3);
9513     setflags = !InITBlock();
9514     shift_t = SRType_LSL;
9515     shift_n = 0;
9516     break;
9517   case eEncodingT2:
9518     Rd = Bits32(opcode, 11, 8);
9519     Rn = Bits32(opcode, 19, 16);
9520     Rm = Bits32(opcode, 3, 0);
9521     setflags = BitIsSet(opcode, 20);
9522     shift_n = DecodeImmShiftThumb(opcode, shift_t);
9523     if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9524       return false;
9525     break;
9526   case eEncodingA1:
9527     Rd = Bits32(opcode, 15, 12);
9528     Rn = Bits32(opcode, 19, 16);
9529     Rm = Bits32(opcode, 3, 0);
9530     setflags = BitIsSet(opcode, 20);
9531     shift_n = DecodeImmShiftARM(opcode, shift_t);
9532 
9533     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9534     // instructions;
9535     if (Rd == 15 && setflags)
9536       return EmulateSUBSPcLrEtc(opcode, encoding);
9537     break;
9538   default:
9539     return false;
9540   }
9541   // Read the register value from register Rn.
9542   uint32_t val1 = ReadCoreReg(Rn, &success);
9543   if (!success)
9544     return false;
9545 
9546   // Read the register value from register Rm.
9547   uint32_t val2 = ReadCoreReg(Rm, &success);
9548   if (!success)
9549     return false;
9550 
9551   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9552   if (!success)
9553     return false;
9554   AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9555 
9556   EmulateInstruction::Context context;
9557   context.type = EmulateInstruction::eContextImmediate;
9558   context.SetNoArgs();
9559   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9560                                    res.carry_out, res.overflow);
9561 }
9562 
9563 // This instruction subtracts an immediate value from a register value, and
9564 // writes the result to the destination register.  It can optionally update the
9565 // condition flags based on the result.
9566 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9567                                                const ARMEncoding encoding) {
9568 #if 0
9569     // ARM pseudo code...
9570     if ConditionPassed() then
9571         EncodingSpecificOperations();
9572         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9573         R[d] = result;
9574         if setflags then
9575             APSR.N = result<31>;
9576             APSR.Z = IsZeroBit(result);
9577             APSR.C = carry;
9578             APSR.V = overflow;
9579 #endif
9580 
9581   bool success = false;
9582 
9583   uint32_t Rd; // the destination register
9584   uint32_t Rn; // the first operand
9585   bool setflags;
9586   uint32_t imm32; // the immediate value to be subtracted from the value
9587                   // obtained from Rn
9588   switch (encoding) {
9589   case eEncodingT1:
9590     Rd = Bits32(opcode, 2, 0);
9591     Rn = Bits32(opcode, 5, 3);
9592     setflags = !InITBlock();
9593     imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9594     break;
9595   case eEncodingT2:
9596     Rd = Rn = Bits32(opcode, 10, 8);
9597     setflags = !InITBlock();
9598     imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9599     break;
9600   case eEncodingT3:
9601     Rd = Bits32(opcode, 11, 8);
9602     Rn = Bits32(opcode, 19, 16);
9603     setflags = BitIsSet(opcode, 20);
9604     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9605 
9606     // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9607     if (Rd == 15 && setflags)
9608       return EmulateCMPImm(opcode, eEncodingT2);
9609 
9610     // if Rn == '1101' then SEE SUB (SP minus immediate);
9611     if (Rn == 13)
9612       return EmulateSUBSPImm(opcode, eEncodingT2);
9613 
9614     // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9615     if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9616       return false;
9617     break;
9618   case eEncodingT4:
9619     Rd = Bits32(opcode, 11, 8);
9620     Rn = Bits32(opcode, 19, 16);
9621     setflags = BitIsSet(opcode, 20);
9622     imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9623 
9624     // if Rn == '1111' then SEE ADR;
9625     if (Rn == 15)
9626       return EmulateADR(opcode, eEncodingT2);
9627 
9628     // if Rn == '1101' then SEE SUB (SP minus immediate);
9629     if (Rn == 13)
9630       return EmulateSUBSPImm(opcode, eEncodingT3);
9631 
9632     if (BadReg(Rd))
9633       return false;
9634     break;
9635   default:
9636     return false;
9637   }
9638   // Read the register value from the operand register Rn.
9639   uint32_t reg_val = ReadCoreReg(Rn, &success);
9640   if (!success)
9641     return false;
9642 
9643   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9644 
9645   EmulateInstruction::Context context;
9646   context.type = EmulateInstruction::eContextImmediate;
9647   context.SetNoArgs();
9648 
9649   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9650                                    res.carry_out, res.overflow);
9651 }
9652 
9653 // This instruction subtracts an immediate value from a register value, and
9654 // writes the result to the destination register.  It can optionally update the
9655 // condition flags based on the result.
9656 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9657                                              const ARMEncoding encoding) {
9658 #if 0
9659     // ARM pseudo code...
9660     if ConditionPassed() then
9661         EncodingSpecificOperations();
9662         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9663         if d == 15 then
9664             ALUWritePC(result); // setflags is always FALSE here
9665         else
9666             R[d] = result;
9667             if setflags then
9668                 APSR.N = result<31>;
9669                 APSR.Z = IsZeroBit(result);
9670                 APSR.C = carry;
9671                 APSR.V = overflow;
9672 #endif
9673 
9674   bool success = false;
9675 
9676   if (ConditionPassed(opcode)) {
9677     uint32_t Rd; // the destination register
9678     uint32_t Rn; // the first operand
9679     bool setflags;
9680     uint32_t imm32; // the immediate value to be subtracted from the value
9681                     // obtained from Rn
9682     switch (encoding) {
9683     case eEncodingA1:
9684       Rd = Bits32(opcode, 15, 12);
9685       Rn = Bits32(opcode, 19, 16);
9686       setflags = BitIsSet(opcode, 20);
9687       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9688 
9689       // if Rn == '1111' && S == '0' then SEE ADR;
9690       if (Rn == 15 && !setflags)
9691         return EmulateADR(opcode, eEncodingA2);
9692 
9693       // if Rn == '1101' then SEE SUB (SP minus immediate);
9694       if (Rn == 13)
9695         return EmulateSUBSPImm(opcode, eEncodingA1);
9696 
9697       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9698       // instructions;
9699       if (Rd == 15 && setflags)
9700         return EmulateSUBSPcLrEtc(opcode, encoding);
9701       break;
9702     default:
9703       return false;
9704     }
9705     // Read the register value from the operand register Rn.
9706     uint32_t reg_val = ReadCoreReg(Rn, &success);
9707     if (!success)
9708       return false;
9709 
9710     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9711 
9712     EmulateInstruction::Context context;
9713     if (Rd == 13)
9714       context.type = EmulateInstruction::eContextAdjustStackPointer;
9715     else
9716       context.type = EmulateInstruction::eContextRegisterPlusOffset;
9717 
9718     std::optional<RegisterInfo> dwarf_reg =
9719         GetRegisterInfo(eRegisterKindDWARF, Rn);
9720     int64_t imm32_signed = imm32;
9721     context.SetRegisterPlusOffset(*dwarf_reg, -imm32_signed);
9722 
9723     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9724                                    res.carry_out, res.overflow))
9725       return false;
9726   }
9727   return true;
9728 }
9729 
9730 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9731 // register value and an immediate value.  It updates the condition flags based
9732 // on the result, and discards the result.
9733 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9734                                           const ARMEncoding encoding) {
9735 #if 0
9736     // ARM pseudo code...
9737     if ConditionPassed() then
9738         EncodingSpecificOperations();
9739         result = R[n] EOR imm32;
9740         APSR.N = result<31>;
9741         APSR.Z = IsZeroBit(result);
9742         APSR.C = carry;
9743         // APSR.V unchanged
9744 #endif
9745 
9746   bool success = false;
9747 
9748   if (ConditionPassed(opcode)) {
9749     uint32_t Rn;
9750     uint32_t
9751         imm32; // the immediate value to be ANDed to the value obtained from Rn
9752     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9753     switch (encoding) {
9754     case eEncodingT1:
9755       Rn = Bits32(opcode, 19, 16);
9756       imm32 = ThumbExpandImm_C(
9757           opcode, APSR_C,
9758           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9759       if (BadReg(Rn))
9760         return false;
9761       break;
9762     case eEncodingA1:
9763       Rn = Bits32(opcode, 19, 16);
9764       imm32 =
9765           ARMExpandImm_C(opcode, APSR_C,
9766                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9767       break;
9768     default:
9769       return false;
9770     }
9771 
9772     // Read the first operand.
9773     uint32_t val1 = ReadCoreReg(Rn, &success);
9774     if (!success)
9775       return false;
9776 
9777     uint32_t result = val1 ^ imm32;
9778 
9779     EmulateInstruction::Context context;
9780     context.type = EmulateInstruction::eContextImmediate;
9781     context.SetNoArgs();
9782 
9783     if (!WriteFlags(context, result, carry))
9784       return false;
9785   }
9786   return true;
9787 }
9788 
9789 // Test Equivalence (register) performs a bitwise exclusive OR operation on a
9790 // register value and an optionally-shifted register value.  It updates the
9791 // condition flags based on the result, and discards the result.
9792 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9793                                           const ARMEncoding encoding) {
9794 #if 0
9795     // ARM pseudo code...
9796     if ConditionPassed() then
9797         EncodingSpecificOperations();
9798         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9799         result = R[n] EOR shifted;
9800         APSR.N = result<31>;
9801         APSR.Z = IsZeroBit(result);
9802         APSR.C = carry;
9803         // APSR.V unchanged
9804 #endif
9805 
9806   bool success = false;
9807 
9808   if (ConditionPassed(opcode)) {
9809     uint32_t Rn, Rm;
9810     ARM_ShifterType shift_t;
9811     uint32_t shift_n; // the shift applied to the value read from Rm
9812     uint32_t carry;
9813     switch (encoding) {
9814     case eEncodingT1:
9815       Rn = Bits32(opcode, 19, 16);
9816       Rm = Bits32(opcode, 3, 0);
9817       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9818       if (BadReg(Rn) || BadReg(Rm))
9819         return false;
9820       break;
9821     case eEncodingA1:
9822       Rn = Bits32(opcode, 19, 16);
9823       Rm = Bits32(opcode, 3, 0);
9824       shift_n = DecodeImmShiftARM(opcode, shift_t);
9825       break;
9826     default:
9827       return false;
9828     }
9829 
9830     // Read the first operand.
9831     uint32_t val1 = ReadCoreReg(Rn, &success);
9832     if (!success)
9833       return false;
9834 
9835     // Read the second operand.
9836     uint32_t val2 = ReadCoreReg(Rm, &success);
9837     if (!success)
9838       return false;
9839 
9840     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9841     if (!success)
9842       return false;
9843     uint32_t result = val1 ^ shifted;
9844 
9845     EmulateInstruction::Context context;
9846     context.type = EmulateInstruction::eContextImmediate;
9847     context.SetNoArgs();
9848 
9849     if (!WriteFlags(context, result, carry))
9850       return false;
9851   }
9852   return true;
9853 }
9854 
9855 // Test (immediate) performs a bitwise AND operation on a register value and an
9856 // immediate value. It updates the condition flags based on the result, and
9857 // discards the result.
9858 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9859                                           const ARMEncoding encoding) {
9860 #if 0
9861     // ARM pseudo code...
9862     if ConditionPassed() then
9863         EncodingSpecificOperations();
9864         result = R[n] AND imm32;
9865         APSR.N = result<31>;
9866         APSR.Z = IsZeroBit(result);
9867         APSR.C = carry;
9868         // APSR.V unchanged
9869 #endif
9870 
9871   bool success = false;
9872 
9873   if (ConditionPassed(opcode)) {
9874     uint32_t Rn;
9875     uint32_t
9876         imm32; // the immediate value to be ANDed to the value obtained from Rn
9877     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9878     switch (encoding) {
9879     case eEncodingT1:
9880       Rn = Bits32(opcode, 19, 16);
9881       imm32 = ThumbExpandImm_C(
9882           opcode, APSR_C,
9883           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9884       if (BadReg(Rn))
9885         return false;
9886       break;
9887     case eEncodingA1:
9888       Rn = Bits32(opcode, 19, 16);
9889       imm32 =
9890           ARMExpandImm_C(opcode, APSR_C,
9891                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9892       break;
9893     default:
9894       return false;
9895     }
9896 
9897     // Read the first operand.
9898     uint32_t val1 = ReadCoreReg(Rn, &success);
9899     if (!success)
9900       return false;
9901 
9902     uint32_t result = val1 & imm32;
9903 
9904     EmulateInstruction::Context context;
9905     context.type = EmulateInstruction::eContextImmediate;
9906     context.SetNoArgs();
9907 
9908     if (!WriteFlags(context, result, carry))
9909       return false;
9910   }
9911   return true;
9912 }
9913 
9914 // Test (register) performs a bitwise AND operation on a register value and an
9915 // optionally-shifted register value. It updates the condition flags based on
9916 // the result, and discards the result.
9917 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9918                                           const ARMEncoding encoding) {
9919 #if 0
9920     // ARM pseudo code...
9921     if ConditionPassed() then
9922         EncodingSpecificOperations();
9923         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9924         result = R[n] AND shifted;
9925         APSR.N = result<31>;
9926         APSR.Z = IsZeroBit(result);
9927         APSR.C = carry;
9928         // APSR.V unchanged
9929 #endif
9930 
9931   bool success = false;
9932 
9933   if (ConditionPassed(opcode)) {
9934     uint32_t Rn, Rm;
9935     ARM_ShifterType shift_t;
9936     uint32_t shift_n; // the shift applied to the value read from Rm
9937     uint32_t carry;
9938     switch (encoding) {
9939     case eEncodingT1:
9940       Rn = Bits32(opcode, 2, 0);
9941       Rm = Bits32(opcode, 5, 3);
9942       shift_t = SRType_LSL;
9943       shift_n = 0;
9944       break;
9945     case eEncodingT2:
9946       Rn = Bits32(opcode, 19, 16);
9947       Rm = Bits32(opcode, 3, 0);
9948       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9949       if (BadReg(Rn) || BadReg(Rm))
9950         return false;
9951       break;
9952     case eEncodingA1:
9953       Rn = Bits32(opcode, 19, 16);
9954       Rm = Bits32(opcode, 3, 0);
9955       shift_n = DecodeImmShiftARM(opcode, shift_t);
9956       break;
9957     default:
9958       return false;
9959     }
9960 
9961     // Read the first operand.
9962     uint32_t val1 = ReadCoreReg(Rn, &success);
9963     if (!success)
9964       return false;
9965 
9966     // Read the second operand.
9967     uint32_t val2 = ReadCoreReg(Rm, &success);
9968     if (!success)
9969       return false;
9970 
9971     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9972     if (!success)
9973       return false;
9974     uint32_t result = val1 & shifted;
9975 
9976     EmulateInstruction::Context context;
9977     context.type = EmulateInstruction::eContextImmediate;
9978     context.SetNoArgs();
9979 
9980     if (!WriteFlags(context, result, carry))
9981       return false;
9982   }
9983   return true;
9984 }
9985 
9986 // A8.6.216 SUB (SP minus register)
9987 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
9988                                             const ARMEncoding encoding) {
9989 #if 0
9990     if ConditionPassed() then
9991         EncodingSpecificOperations();
9992         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9993         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9994         if d == 15 then // Can only occur for ARM encoding
9995             ALUWritePC(result); // setflags is always FALSE here
9996         else
9997             R[d] = result;
9998             if setflags then
9999                 APSR.N = result<31>;
10000                 APSR.Z = IsZeroBit(result);
10001                 APSR.C = carry;
10002                 APSR.V = overflow;
10003 #endif
10004 
10005   bool success = false;
10006 
10007   if (ConditionPassed(opcode)) {
10008     uint32_t d;
10009     uint32_t m;
10010     bool setflags;
10011     ARM_ShifterType shift_t;
10012     uint32_t shift_n;
10013 
10014     switch (encoding) {
10015     case eEncodingT1:
10016       // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10017       d = Bits32(opcode, 11, 8);
10018       m = Bits32(opcode, 3, 0);
10019       setflags = BitIsSet(opcode, 20);
10020 
10021       // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10022       shift_n = DecodeImmShiftThumb(opcode, shift_t);
10023 
10024       // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10025       // UNPREDICTABLE;
10026       if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10027         return false;
10028 
10029       // if d == 15 || BadReg(m) then UNPREDICTABLE;
10030       if ((d == 15) || BadReg(m))
10031         return false;
10032       break;
10033 
10034     case eEncodingA1:
10035       // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10036       d = Bits32(opcode, 15, 12);
10037       m = Bits32(opcode, 3, 0);
10038       setflags = BitIsSet(opcode, 20);
10039 
10040       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10041       // instructions;
10042       if (d == 15 && setflags)
10043         EmulateSUBSPcLrEtc(opcode, encoding);
10044 
10045       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10046       shift_n = DecodeImmShiftARM(opcode, shift_t);
10047       break;
10048 
10049     default:
10050       return false;
10051     }
10052 
10053     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10054     uint32_t Rm = ReadCoreReg(m, &success);
10055     if (!success)
10056       return false;
10057 
10058     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10059     if (!success)
10060       return false;
10061 
10062     // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10063     uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10064     if (!success)
10065       return false;
10066 
10067     AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10068 
10069     EmulateInstruction::Context context;
10070     context.type = eContextArithmetic;
10071     std::optional<RegisterInfo> sp_reg =
10072         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
10073     std::optional<RegisterInfo> dwarf_reg =
10074         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10075     context.SetRegisterRegisterOperands(*sp_reg, *dwarf_reg);
10076 
10077     if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10078                                    res.carry_out, res.overflow))
10079       return false;
10080   }
10081   return true;
10082 }
10083 
10084 // A8.6.7 ADD (register-shifted register)
10085 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10086                                                const ARMEncoding encoding) {
10087 #if 0
10088     if ConditionPassed() then
10089         EncodingSpecificOperations();
10090         shift_n = UInt(R[s]<7:0>);
10091         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10092         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10093         R[d] = result;
10094         if setflags then
10095             APSR.N = result<31>;
10096             APSR.Z = IsZeroBit(result);
10097             APSR.C = carry;
10098             APSR.V = overflow;
10099 #endif
10100 
10101   bool success = false;
10102 
10103   if (ConditionPassed(opcode)) {
10104     uint32_t d;
10105     uint32_t n;
10106     uint32_t m;
10107     uint32_t s;
10108     bool setflags;
10109     ARM_ShifterType shift_t;
10110 
10111     switch (encoding) {
10112     case eEncodingA1:
10113       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10114       d = Bits32(opcode, 15, 12);
10115       n = Bits32(opcode, 19, 16);
10116       m = Bits32(opcode, 3, 0);
10117       s = Bits32(opcode, 11, 8);
10118 
10119       // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10120       setflags = BitIsSet(opcode, 20);
10121       shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10122 
10123       // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10124       if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10125         return false;
10126       break;
10127 
10128     default:
10129       return false;
10130     }
10131 
10132     // shift_n = UInt(R[s]<7:0>);
10133     uint32_t Rs = ReadCoreReg(s, &success);
10134     if (!success)
10135       return false;
10136 
10137     uint32_t shift_n = Bits32(Rs, 7, 0);
10138 
10139     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10140     uint32_t Rm = ReadCoreReg(m, &success);
10141     if (!success)
10142       return false;
10143 
10144     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10145     if (!success)
10146       return false;
10147 
10148     // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10149     uint32_t Rn = ReadCoreReg(n, &success);
10150     if (!success)
10151       return false;
10152 
10153     AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10154 
10155     // R[d] = result;
10156     EmulateInstruction::Context context;
10157     context.type = eContextArithmetic;
10158     std::optional<RegisterInfo> reg_n =
10159         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10160     std::optional<RegisterInfo> reg_m =
10161         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10162 
10163     context.SetRegisterRegisterOperands(*reg_n, *reg_m);
10164 
10165     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10166                                res.result))
10167       return false;
10168 
10169     // if setflags then
10170     // APSR.N = result<31>;
10171     // APSR.Z = IsZeroBit(result);
10172     // APSR.C = carry;
10173     // APSR.V = overflow;
10174     if (setflags)
10175       return WriteFlags(context, res.result, res.carry_out, res.overflow);
10176   }
10177   return true;
10178 }
10179 
10180 // A8.6.213 SUB (register)
10181 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10182                                           const ARMEncoding encoding) {
10183 #if 0
10184     if ConditionPassed() then
10185         EncodingSpecificOperations();
10186         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10187         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10188         if d == 15 then // Can only occur for ARM encoding
10189             ALUWritePC(result); // setflags is always FALSE here
10190         else
10191             R[d] = result;
10192             if setflags then
10193                 APSR.N = result<31>;
10194                 APSR.Z = IsZeroBit(result);
10195                 APSR.C = carry;
10196                 APSR.V = overflow;
10197 #endif
10198 
10199   bool success = false;
10200 
10201   if (ConditionPassed(opcode)) {
10202     uint32_t d;
10203     uint32_t n;
10204     uint32_t m;
10205     bool setflags;
10206     ARM_ShifterType shift_t;
10207     uint32_t shift_n;
10208 
10209     switch (encoding) {
10210     case eEncodingT1:
10211       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10212       d = Bits32(opcode, 2, 0);
10213       n = Bits32(opcode, 5, 3);
10214       m = Bits32(opcode, 8, 6);
10215       setflags = !InITBlock();
10216 
10217       // (shift_t, shift_n) = (SRType_LSL, 0);
10218       shift_t = SRType_LSL;
10219       shift_n = 0;
10220 
10221       break;
10222 
10223     case eEncodingT2:
10224       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10225       d = Bits32(opcode, 11, 8);
10226       n = Bits32(opcode, 19, 16);
10227       m = Bits32(opcode, 3, 0);
10228       setflags = BitIsSet(opcode, 20);
10229 
10230       // if Rd == "1111" && S == "1" then SEE CMP (register);
10231       if (d == 15 && setflags == 1)
10232         return EmulateCMPImm(opcode, eEncodingT3);
10233 
10234       // if Rn == "1101" then SEE SUB (SP minus register);
10235       if (n == 13)
10236         return EmulateSUBSPReg(opcode, eEncodingT1);
10237 
10238       // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10239       shift_n = DecodeImmShiftThumb(opcode, shift_t);
10240 
10241       // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10242       // UNPREDICTABLE;
10243       if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10244           BadReg(m))
10245         return false;
10246 
10247       break;
10248 
10249     case eEncodingA1:
10250       // if Rn == '1101' then SEE SUB (SP minus register);
10251       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10252       d = Bits32(opcode, 15, 12);
10253       n = Bits32(opcode, 19, 16);
10254       m = Bits32(opcode, 3, 0);
10255       setflags = BitIsSet(opcode, 20);
10256 
10257       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10258       // instructions;
10259       if ((d == 15) && setflags)
10260         EmulateSUBSPcLrEtc(opcode, encoding);
10261 
10262       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10263       shift_n = DecodeImmShiftARM(opcode, shift_t);
10264 
10265       break;
10266 
10267     default:
10268       return false;
10269     }
10270 
10271     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10272     uint32_t Rm = ReadCoreReg(m, &success);
10273     if (!success)
10274       return false;
10275 
10276     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10277     if (!success)
10278       return false;
10279 
10280     // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10281     uint32_t Rn = ReadCoreReg(n, &success);
10282     if (!success)
10283       return false;
10284 
10285     AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10286 
10287     // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10288     // // setflags is always FALSE here else
10289     // R[d] = result;
10290     // if setflags then
10291     // APSR.N = result<31>;
10292     // APSR.Z = IsZeroBit(result);
10293     // APSR.C = carry;
10294     // APSR.V = overflow;
10295 
10296     EmulateInstruction::Context context;
10297     context.type = eContextArithmetic;
10298     std::optional<RegisterInfo> reg_n =
10299         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10300     std::optional<RegisterInfo> reg_m =
10301         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10302     context.SetRegisterRegisterOperands(*reg_n, *reg_m);
10303 
10304     if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10305                                    res.carry_out, res.overflow))
10306       return false;
10307   }
10308   return true;
10309 }
10310 
10311 // A8.6.202 STREX
10312 // Store Register Exclusive calculates an address from a base register value
10313 // and an immediate offset, and stores a word from a register to memory if the
10314 // executing processor has exclusive access to the memory addressed.
10315 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10316                                          const ARMEncoding encoding) {
10317 #if 0
10318     if ConditionPassed() then
10319         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10320         address = R[n] + imm32;
10321         if ExclusiveMonitorsPass(address,4) then
10322             MemA[address,4] = R[t];
10323             R[d] = 0;
10324         else
10325             R[d] = 1;
10326 #endif
10327 
10328   bool success = false;
10329 
10330   if (ConditionPassed(opcode)) {
10331     uint32_t d;
10332     uint32_t t;
10333     uint32_t n;
10334     uint32_t imm32;
10335     const uint32_t addr_byte_size = GetAddressByteSize();
10336 
10337     switch (encoding) {
10338     case eEncodingT1:
10339       // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10340       // ZeroExtend(imm8:'00',
10341       // 32);
10342       d = Bits32(opcode, 11, 8);
10343       t = Bits32(opcode, 15, 12);
10344       n = Bits32(opcode, 19, 16);
10345       imm32 = Bits32(opcode, 7, 0) << 2;
10346 
10347       // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10348       if (BadReg(d) || BadReg(t) || (n == 15))
10349         return false;
10350 
10351       // if d == n || d == t then UNPREDICTABLE;
10352       if ((d == n) || (d == t))
10353         return false;
10354 
10355       break;
10356 
10357     case eEncodingA1:
10358       // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10359       // offset
10360       d = Bits32(opcode, 15, 12);
10361       t = Bits32(opcode, 3, 0);
10362       n = Bits32(opcode, 19, 16);
10363       imm32 = 0;
10364 
10365       // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10366       if ((d == 15) || (t == 15) || (n == 15))
10367         return false;
10368 
10369       // if d == n || d == t then UNPREDICTABLE;
10370       if ((d == n) || (d == t))
10371         return false;
10372 
10373       break;
10374 
10375     default:
10376       return false;
10377     }
10378 
10379     // address = R[n] + imm32;
10380     uint32_t Rn = ReadCoreReg(n, &success);
10381     if (!success)
10382       return false;
10383 
10384     addr_t address = Rn + imm32;
10385 
10386     std::optional<RegisterInfo> base_reg =
10387         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10388     std::optional<RegisterInfo> data_reg =
10389         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10390     EmulateInstruction::Context context;
10391     context.type = eContextRegisterStore;
10392     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, imm32);
10393 
10394     // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10395     // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10396     // will say this
10397     //                                                         always return
10398     //                                                         true.
10399     if (true) {
10400       // MemA[address,4] = R[t];
10401       uint32_t Rt =
10402           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10403       if (!success)
10404         return false;
10405 
10406       if (!MemAWrite(context, address, Rt, addr_byte_size))
10407         return false;
10408 
10409       // R[d] = 0;
10410       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10411         return false;
10412     }
10413 #if 0  // unreachable because if true
10414         else
10415         {
10416             // R[d] = 1;
10417             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10418                 return false;
10419         }
10420 #endif // unreachable because if true
10421   }
10422   return true;
10423 }
10424 
10425 // A8.6.197 STRB (immediate, ARM)
10426 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10427                                               const ARMEncoding encoding) {
10428 #if 0
10429     if ConditionPassed() then
10430         EncodingSpecificOperations();
10431         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10432         address = if index then offset_addr else R[n];
10433         MemU[address,1] = R[t]<7:0>;
10434         if wback then R[n] = offset_addr;
10435 #endif
10436 
10437   bool success = false;
10438 
10439   if (ConditionPassed(opcode)) {
10440     uint32_t t;
10441     uint32_t n;
10442     uint32_t imm32;
10443     bool index;
10444     bool add;
10445     bool wback;
10446 
10447     switch (encoding) {
10448     case eEncodingA1:
10449       // if P == '0' && W == '1' then SEE STRBT;
10450       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10451       t = Bits32(opcode, 15, 12);
10452       n = Bits32(opcode, 19, 16);
10453       imm32 = Bits32(opcode, 11, 0);
10454 
10455       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10456       index = BitIsSet(opcode, 24);
10457       add = BitIsSet(opcode, 23);
10458       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10459 
10460       // if t == 15 then UNPREDICTABLE;
10461       if (t == 15)
10462         return false;
10463 
10464       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10465       if (wback && ((n == 15) || (n == t)))
10466         return false;
10467 
10468       break;
10469 
10470     default:
10471       return false;
10472     }
10473 
10474     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10475     uint32_t Rn = ReadCoreReg(n, &success);
10476     if (!success)
10477       return false;
10478 
10479     addr_t offset_addr;
10480     if (add)
10481       offset_addr = Rn + imm32;
10482     else
10483       offset_addr = Rn - imm32;
10484 
10485     // address = if index then offset_addr else R[n];
10486     addr_t address;
10487     if (index)
10488       address = offset_addr;
10489     else
10490       address = Rn;
10491 
10492     // MemU[address,1] = R[t]<7:0>;
10493     uint32_t Rt = ReadCoreReg(t, &success);
10494     if (!success)
10495       return false;
10496 
10497     std::optional<RegisterInfo> base_reg =
10498         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10499     std::optional<RegisterInfo> data_reg =
10500         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10501     EmulateInstruction::Context context;
10502     context.type = eContextRegisterStore;
10503     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
10504 
10505     if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10506       return false;
10507 
10508     // if wback then R[n] = offset_addr;
10509     if (wback) {
10510       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10511                                  offset_addr))
10512         return false;
10513     }
10514   }
10515   return true;
10516 }
10517 
10518 // A8.6.194 STR (immediate, ARM)
10519 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10520                                              const ARMEncoding encoding) {
10521 #if 0
10522     if ConditionPassed() then
10523         EncodingSpecificOperations();
10524         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10525         address = if index then offset_addr else R[n];
10526         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10527         if wback then R[n] = offset_addr;
10528 #endif
10529 
10530   bool success = false;
10531 
10532   if (ConditionPassed(opcode)) {
10533     uint32_t t;
10534     uint32_t n;
10535     uint32_t imm32;
10536     bool index;
10537     bool add;
10538     bool wback;
10539 
10540     const uint32_t addr_byte_size = GetAddressByteSize();
10541 
10542     switch (encoding) {
10543     case eEncodingA1:
10544       // if P == '0' && W == '1' then SEE STRT;
10545       // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10546       // '000000000100' then SEE PUSH;
10547       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10548       t = Bits32(opcode, 15, 12);
10549       n = Bits32(opcode, 19, 16);
10550       imm32 = Bits32(opcode, 11, 0);
10551 
10552       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10553       index = BitIsSet(opcode, 24);
10554       add = BitIsSet(opcode, 23);
10555       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10556 
10557       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10558       if (wback && ((n == 15) || (n == t)))
10559         return false;
10560 
10561       break;
10562 
10563     default:
10564       return false;
10565     }
10566 
10567     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10568     uint32_t Rn = ReadCoreReg(n, &success);
10569     if (!success)
10570       return false;
10571 
10572     addr_t offset_addr;
10573     if (add)
10574       offset_addr = Rn + imm32;
10575     else
10576       offset_addr = Rn - imm32;
10577 
10578     // address = if index then offset_addr else R[n];
10579     addr_t address;
10580     if (index)
10581       address = offset_addr;
10582     else
10583       address = Rn;
10584 
10585     std::optional<RegisterInfo> base_reg =
10586         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10587     std::optional<RegisterInfo> data_reg =
10588         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10589     EmulateInstruction::Context context;
10590     context.type = eContextRegisterStore;
10591     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
10592 
10593     // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10594     uint32_t Rt = ReadCoreReg(t, &success);
10595     if (!success)
10596       return false;
10597 
10598     if (t == 15) {
10599       uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10600       if (!success)
10601         return false;
10602 
10603       if (!MemUWrite(context, address, pc_value, addr_byte_size))
10604         return false;
10605     } else {
10606       if (!MemUWrite(context, address, Rt, addr_byte_size))
10607         return false;
10608     }
10609 
10610     // if wback then R[n] = offset_addr;
10611     if (wback) {
10612       context.type = eContextAdjustBaseRegister;
10613       context.SetImmediate(offset_addr);
10614 
10615       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10616                                  offset_addr))
10617         return false;
10618     }
10619   }
10620   return true;
10621 }
10622 
10623 // A8.6.66 LDRD (immediate)
10624 // Load Register Dual (immediate) calculates an address from a base register
10625 // value and an immediate offset, loads two words from memory, and writes them
10626 // to two registers.  It can use offset, post-indexed, or pre-indexed
10627 // addressing.
10628 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10629                                                  const ARMEncoding encoding) {
10630 #if 0
10631     if ConditionPassed() then
10632         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10633         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10634         address = if index then offset_addr else R[n];
10635         R[t] = MemA[address,4];
10636         R[t2] = MemA[address+4,4];
10637         if wback then R[n] = offset_addr;
10638 #endif
10639 
10640   bool success = false;
10641 
10642   if (ConditionPassed(opcode)) {
10643     uint32_t t;
10644     uint32_t t2;
10645     uint32_t n;
10646     uint32_t imm32;
10647     bool index;
10648     bool add;
10649     bool wback;
10650 
10651     switch (encoding) {
10652     case eEncodingT1:
10653       // if P == '0' && W == '0' then SEE 'Related encodings';
10654       // if Rn == '1111' then SEE LDRD (literal);
10655       // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10656       // ZeroExtend(imm8:'00', 32);
10657       t = Bits32(opcode, 15, 12);
10658       t2 = Bits32(opcode, 11, 8);
10659       n = Bits32(opcode, 19, 16);
10660       imm32 = Bits32(opcode, 7, 0) << 2;
10661 
10662       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10663       index = BitIsSet(opcode, 24);
10664       add = BitIsSet(opcode, 23);
10665       wback = BitIsSet(opcode, 21);
10666 
10667       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10668       if (wback && ((n == t) || (n == t2)))
10669         return false;
10670 
10671       // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10672       if (BadReg(t) || BadReg(t2) || (t == t2))
10673         return false;
10674 
10675       break;
10676 
10677     case eEncodingA1:
10678       // if Rn == '1111' then SEE LDRD (literal);
10679       // if Rt<0> == '1' then UNPREDICTABLE;
10680       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10681       // 32);
10682       t = Bits32(opcode, 15, 12);
10683       if (BitIsSet(t, 0))
10684         return false;
10685       t2 = t + 1;
10686       n = Bits32(opcode, 19, 16);
10687       imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10688 
10689       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10690       index = BitIsSet(opcode, 24);
10691       add = BitIsSet(opcode, 23);
10692       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10693 
10694       // if P == '0' && W == '1' then UNPREDICTABLE;
10695       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10696         return false;
10697 
10698       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10699       if (wback && ((n == t) || (n == t2)))
10700         return false;
10701 
10702       // if t2 == 15 then UNPREDICTABLE;
10703       if (t2 == 15)
10704         return false;
10705 
10706       break;
10707 
10708     default:
10709       return false;
10710     }
10711 
10712     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10713     uint32_t Rn = ReadCoreReg(n, &success);
10714     if (!success)
10715       return false;
10716 
10717     addr_t offset_addr;
10718     if (add)
10719       offset_addr = Rn + imm32;
10720     else
10721       offset_addr = Rn - imm32;
10722 
10723     // address = if index then offset_addr else R[n];
10724     addr_t address;
10725     if (index)
10726       address = offset_addr;
10727     else
10728       address = Rn;
10729 
10730     // R[t] = MemA[address,4];
10731 
10732     EmulateInstruction::Context context;
10733     if (n == 13)
10734       context.type = eContextPopRegisterOffStack;
10735     else
10736       context.type = eContextRegisterLoad;
10737     context.SetAddress(address);
10738 
10739     const uint32_t addr_byte_size = GetAddressByteSize();
10740     uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10741     if (!success)
10742       return false;
10743 
10744     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10745       return false;
10746 
10747     // R[t2] = MemA[address+4,4];
10748     context.SetAddress(address + 4);
10749     data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10750     if (!success)
10751       return false;
10752 
10753     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10754                                data))
10755       return false;
10756 
10757     // if wback then R[n] = offset_addr;
10758     if (wback) {
10759       context.type = eContextAdjustBaseRegister;
10760       context.SetAddress(offset_addr);
10761 
10762       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10763                                  offset_addr))
10764         return false;
10765     }
10766   }
10767   return true;
10768 }
10769 
10770 // A8.6.68 LDRD (register)
10771 // Load Register Dual (register) calculates an address from a base register
10772 // value and a register offset, loads two words from memory, and writes them to
10773 // two registers.  It can use offset, post-indexed or pre-indexed addressing.
10774 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10775                                                 const ARMEncoding encoding) {
10776 #if 0
10777     if ConditionPassed() then
10778         EncodingSpecificOperations();
10779         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10780         address = if index then offset_addr else R[n];
10781         R[t] = MemA[address,4];
10782         R[t2] = MemA[address+4,4];
10783         if wback then R[n] = offset_addr;
10784 #endif
10785 
10786   bool success = false;
10787 
10788   if (ConditionPassed(opcode)) {
10789     uint32_t t;
10790     uint32_t t2;
10791     uint32_t n;
10792     uint32_t m;
10793     bool index;
10794     bool add;
10795     bool wback;
10796 
10797     switch (encoding) {
10798     case eEncodingA1:
10799       // if Rt<0> == '1' then UNPREDICTABLE;
10800       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10801       t = Bits32(opcode, 15, 12);
10802       if (BitIsSet(t, 0))
10803         return false;
10804       t2 = t + 1;
10805       n = Bits32(opcode, 19, 16);
10806       m = Bits32(opcode, 3, 0);
10807 
10808       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10809       index = BitIsSet(opcode, 24);
10810       add = BitIsSet(opcode, 23);
10811       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10812 
10813       // if P == '0' && W == '1' then UNPREDICTABLE;
10814       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10815         return false;
10816 
10817       // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10818       if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10819         return false;
10820 
10821       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10822       if (wback && ((n == 15) || (n == t) || (n == t2)))
10823         return false;
10824 
10825       // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10826       if ((ArchVersion() < 6) && wback && (m == n))
10827         return false;
10828       break;
10829 
10830     default:
10831       return false;
10832     }
10833 
10834     uint32_t Rn = ReadCoreReg(n, &success);
10835     if (!success)
10836       return false;
10837 
10838     uint32_t Rm = ReadCoreReg(m, &success);
10839     if (!success)
10840       return false;
10841 
10842     // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10843     addr_t offset_addr;
10844     if (add)
10845       offset_addr = Rn + Rm;
10846     else
10847       offset_addr = Rn - Rm;
10848 
10849     // address = if index then offset_addr else R[n];
10850     addr_t address;
10851     if (index)
10852       address = offset_addr;
10853     else
10854       address = Rn;
10855 
10856     EmulateInstruction::Context context;
10857     if (n == 13)
10858       context.type = eContextPopRegisterOffStack;
10859     else
10860       context.type = eContextRegisterLoad;
10861     context.SetAddress(address);
10862 
10863     // R[t] = MemA[address,4];
10864     const uint32_t addr_byte_size = GetAddressByteSize();
10865     uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10866     if (!success)
10867       return false;
10868 
10869     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10870       return false;
10871 
10872     // R[t2] = MemA[address+4,4];
10873 
10874     data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10875     if (!success)
10876       return false;
10877 
10878     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10879                                data))
10880       return false;
10881 
10882     // if wback then R[n] = offset_addr;
10883     if (wback) {
10884       context.type = eContextAdjustBaseRegister;
10885       context.SetAddress(offset_addr);
10886 
10887       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10888                                  offset_addr))
10889         return false;
10890     }
10891   }
10892   return true;
10893 }
10894 
10895 // A8.6.200 STRD (immediate)
10896 // Store Register Dual (immediate) calculates an address from a base register
10897 // value and an immediate offset, and stores two words from two registers to
10898 // memory.  It can use offset, post-indexed, or pre-indexed addressing.
10899 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10900                                            const ARMEncoding encoding) {
10901 #if 0
10902     if ConditionPassed() then
10903         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10904         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10905         address = if index then offset_addr else R[n];
10906         MemA[address,4] = R[t];
10907         MemA[address+4,4] = R[t2];
10908         if wback then R[n] = offset_addr;
10909 #endif
10910 
10911   bool success = false;
10912 
10913   if (ConditionPassed(opcode)) {
10914     uint32_t t;
10915     uint32_t t2;
10916     uint32_t n;
10917     uint32_t imm32;
10918     bool index;
10919     bool add;
10920     bool wback;
10921 
10922     switch (encoding) {
10923     case eEncodingT1:
10924       // if P == '0' && W == '0' then SEE 'Related encodings';
10925       // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10926       // ZeroExtend(imm8:'00', 32);
10927       t = Bits32(opcode, 15, 12);
10928       t2 = Bits32(opcode, 11, 8);
10929       n = Bits32(opcode, 19, 16);
10930       imm32 = Bits32(opcode, 7, 0) << 2;
10931 
10932       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10933       index = BitIsSet(opcode, 24);
10934       add = BitIsSet(opcode, 23);
10935       wback = BitIsSet(opcode, 21);
10936 
10937       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10938       if (wback && ((n == t) || (n == t2)))
10939         return false;
10940 
10941       // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10942       if ((n == 15) || BadReg(t) || BadReg(t2))
10943         return false;
10944 
10945       break;
10946 
10947     case eEncodingA1:
10948       // if Rt<0> == '1' then UNPREDICTABLE;
10949       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10950       // 32);
10951       t = Bits32(opcode, 15, 12);
10952       if (BitIsSet(t, 0))
10953         return false;
10954 
10955       t2 = t + 1;
10956       n = Bits32(opcode, 19, 16);
10957       imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10958 
10959       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10960       index = BitIsSet(opcode, 24);
10961       add = BitIsSet(opcode, 23);
10962       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10963 
10964       // if P == '0' && W == '1' then UNPREDICTABLE;
10965       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10966         return false;
10967 
10968       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10969       if (wback && ((n == 15) || (n == t) || (n == t2)))
10970         return false;
10971 
10972       // if t2 == 15 then UNPREDICTABLE;
10973       if (t2 == 15)
10974         return false;
10975 
10976       break;
10977 
10978     default:
10979       return false;
10980     }
10981 
10982     std::optional<RegisterInfo> base_reg =
10983         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10984 
10985     uint32_t Rn = ReadCoreReg(n, &success);
10986     if (!success)
10987       return false;
10988 
10989     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10990     addr_t offset_addr;
10991     if (add)
10992       offset_addr = Rn + imm32;
10993     else
10994       offset_addr = Rn - imm32;
10995 
10996     // address = if index then offset_addr else R[n];
10997     addr_t address;
10998     if (index)
10999       address = offset_addr;
11000     else
11001       address = Rn;
11002 
11003     // MemA[address,4] = R[t];
11004     std::optional<RegisterInfo> data_reg =
11005         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
11006 
11007     uint32_t data = ReadCoreReg(t, &success);
11008     if (!success)
11009       return false;
11010 
11011     EmulateInstruction::Context context;
11012     if (n == 13)
11013       context.type = eContextPushRegisterOnStack;
11014     else
11015       context.type = eContextRegisterStore;
11016     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
11017 
11018     const uint32_t addr_byte_size = GetAddressByteSize();
11019 
11020     if (!MemAWrite(context, address, data, addr_byte_size))
11021       return false;
11022 
11023     // MemA[address+4,4] = R[t2];
11024     data_reg = GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2);
11025     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11026                                             (address + 4) - Rn);
11027 
11028     data = ReadCoreReg(t2, &success);
11029     if (!success)
11030       return false;
11031 
11032     if (!MemAWrite(context, address + 4, data, addr_byte_size))
11033       return false;
11034 
11035     // if wback then R[n] = offset_addr;
11036     if (wback) {
11037       if (n == 13)
11038         context.type = eContextAdjustStackPointer;
11039       else
11040         context.type = eContextAdjustBaseRegister;
11041       context.SetAddress(offset_addr);
11042 
11043       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11044                                  offset_addr))
11045         return false;
11046     }
11047   }
11048   return true;
11049 }
11050 
11051 // A8.6.201 STRD (register)
11052 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11053                                            const ARMEncoding encoding) {
11054 #if 0
11055     if ConditionPassed() then
11056         EncodingSpecificOperations();
11057         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11058         address = if index then offset_addr else R[n];
11059         MemA[address,4] = R[t];
11060         MemA[address+4,4] = R[t2];
11061         if wback then R[n] = offset_addr;
11062 #endif
11063 
11064   bool success = false;
11065 
11066   if (ConditionPassed(opcode)) {
11067     uint32_t t;
11068     uint32_t t2;
11069     uint32_t n;
11070     uint32_t m;
11071     bool index;
11072     bool add;
11073     bool wback;
11074 
11075     switch (encoding) {
11076     case eEncodingA1:
11077       // if Rt<0> == '1' then UNPREDICTABLE;
11078       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11079       t = Bits32(opcode, 15, 12);
11080       if (BitIsSet(t, 0))
11081         return false;
11082 
11083       t2 = t + 1;
11084       n = Bits32(opcode, 19, 16);
11085       m = Bits32(opcode, 3, 0);
11086 
11087       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11088       index = BitIsSet(opcode, 24);
11089       add = BitIsSet(opcode, 23);
11090       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11091 
11092       // if P == '0' && W == '1' then UNPREDICTABLE;
11093       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11094         return false;
11095 
11096       // if t2 == 15 || m == 15 then UNPREDICTABLE;
11097       if ((t2 == 15) || (m == 15))
11098         return false;
11099 
11100       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11101       if (wback && ((n == 15) || (n == t) || (n == t2)))
11102         return false;
11103 
11104       // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11105       if ((ArchVersion() < 6) && wback && (m == n))
11106         return false;
11107 
11108       break;
11109 
11110     default:
11111       return false;
11112     }
11113 
11114     uint32_t Rn = ReadCoreReg(n, &success);
11115     if (!success)
11116       return false;
11117 
11118     uint32_t Rm = ReadCoreReg(m, &success);
11119     if (!success)
11120       return false;
11121 
11122     // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11123     addr_t offset_addr;
11124     if (add)
11125       offset_addr = Rn + Rm;
11126     else
11127       offset_addr = Rn - Rm;
11128 
11129     // address = if index then offset_addr else R[n];
11130     addr_t address;
11131     if (index)
11132       address = offset_addr;
11133     else
11134       address = Rn;
11135     // MemA[address,4] = R[t];
11136     uint32_t Rt = ReadCoreReg(t, &success);
11137     if (!success)
11138       return false;
11139 
11140     EmulateInstruction::Context context;
11141     if (t == 13)
11142       context.type = eContextPushRegisterOnStack;
11143     else
11144       context.type = eContextRegisterStore;
11145 
11146     std::optional<RegisterInfo> base_reg =
11147         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11148     std::optional<RegisterInfo> offset_reg =
11149         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
11150     std::optional<RegisterInfo> data_reg =
11151         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
11152     context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
11153                                                     *data_reg);
11154 
11155     const uint32_t addr_byte_size = GetAddressByteSize();
11156 
11157     if (!MemAWrite(context, address, Rt, addr_byte_size))
11158       return false;
11159 
11160     // MemA[address+4,4] = R[t2];
11161     uint32_t Rt2 = ReadCoreReg(t2, &success);
11162     if (!success)
11163       return false;
11164 
11165     data_reg = GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2);
11166 
11167     context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
11168                                                     *data_reg);
11169 
11170     if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11171       return false;
11172 
11173     // if wback then R[n] = offset_addr;
11174     if (wback) {
11175       context.type = eContextAdjustBaseRegister;
11176       context.SetAddress(offset_addr);
11177 
11178       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11179                                  offset_addr))
11180         return false;
11181     }
11182   }
11183   return true;
11184 }
11185 
11186 // A8.6.319 VLDM
11187 // Vector Load Multiple loads multiple extension registers from consecutive
11188 // memory locations using an address from an ARM core register.
11189 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11190                                         const ARMEncoding encoding) {
11191 #if 0
11192     if ConditionPassed() then
11193         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11194         address = if add then R[n] else R[n]-imm32;
11195         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11196         for r = 0 to regs-1
11197             if single_regs then
11198                 S[d+r] = MemA[address,4]; address = address+4;
11199             else
11200                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11201                 // Combine the word-aligned words in the correct order for
11202                 // current endianness.
11203                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11204 #endif
11205 
11206   bool success = false;
11207 
11208   if (ConditionPassed(opcode)) {
11209     bool single_regs;
11210     bool add;
11211     bool wback;
11212     uint32_t d;
11213     uint32_t n;
11214     uint32_t imm32;
11215     uint32_t regs;
11216 
11217     switch (encoding) {
11218     case eEncodingT1:
11219     case eEncodingA1:
11220       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11221       // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11222       // if P == '1' && W == '0' then SEE VLDR;
11223       // if P == U && W == '1' then UNDEFINED;
11224       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11225         return false;
11226 
11227       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11228       // !), 101 (DB with !)
11229       // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11230       single_regs = false;
11231       add = BitIsSet(opcode, 23);
11232       wback = BitIsSet(opcode, 21);
11233 
11234       // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11235       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11236       n = Bits32(opcode, 19, 16);
11237       imm32 = Bits32(opcode, 7, 0) << 2;
11238 
11239       // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11240       regs = Bits32(opcode, 7, 0) / 2;
11241 
11242       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11243       // UNPREDICTABLE;
11244       if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11245         return false;
11246 
11247       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11248       if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11249         return false;
11250 
11251       break;
11252 
11253     case eEncodingT2:
11254     case eEncodingA2:
11255       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11256       // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11257       // if P == '1' && W == '0' then SEE VLDR;
11258       // if P == U && W == '1' then UNDEFINED;
11259       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11260         return false;
11261 
11262       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11263       // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11264       // == '1'); d =
11265       // UInt(Vd:D); n = UInt(Rn);
11266       single_regs = true;
11267       add = BitIsSet(opcode, 23);
11268       wback = BitIsSet(opcode, 21);
11269       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11270       n = Bits32(opcode, 19, 16);
11271 
11272       // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11273       imm32 = Bits32(opcode, 7, 0) << 2;
11274       regs = Bits32(opcode, 7, 0);
11275 
11276       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11277       // UNPREDICTABLE;
11278       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11279         return false;
11280 
11281       // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11282       if ((regs == 0) || ((d + regs) > 32))
11283         return false;
11284       break;
11285 
11286     default:
11287       return false;
11288     }
11289 
11290     uint32_t Rn = ReadCoreReg(n, &success);
11291     if (!success)
11292       return false;
11293 
11294     // address = if add then R[n] else R[n]-imm32;
11295     addr_t address;
11296     if (add)
11297       address = Rn;
11298     else
11299       address = Rn - imm32;
11300 
11301     // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11302     EmulateInstruction::Context context;
11303 
11304     if (wback) {
11305       uint32_t value;
11306       if (add)
11307         value = Rn + imm32;
11308       else
11309         value = Rn - imm32;
11310 
11311       context.type = eContextAdjustBaseRegister;
11312       context.SetImmediateSigned(value - Rn);
11313       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11314                                  value))
11315         return false;
11316     }
11317 
11318     const uint32_t addr_byte_size = GetAddressByteSize();
11319     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11320 
11321     context.type = eContextRegisterLoad;
11322 
11323     std::optional<RegisterInfo> base_reg =
11324         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11325 
11326     // for r = 0 to regs-1
11327     for (uint32_t r = 0; r < regs; ++r) {
11328       if (single_regs) {
11329         // S[d+r] = MemA[address,4]; address = address+4;
11330         context.SetRegisterPlusOffset(*base_reg, address - Rn);
11331 
11332         uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11333         if (!success)
11334           return false;
11335 
11336         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11337                                    start_reg + d + r, data))
11338           return false;
11339 
11340         address = address + 4;
11341       } else {
11342         // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11343         // address+8;
11344         context.SetRegisterPlusOffset(*base_reg, address - Rn);
11345         uint32_t word1 =
11346             MemARead(context, address, addr_byte_size, 0, &success);
11347         if (!success)
11348           return false;
11349 
11350         context.SetRegisterPlusOffset(*base_reg, (address + 4) - Rn);
11351         uint32_t word2 =
11352             MemARead(context, address + 4, addr_byte_size, 0, &success);
11353         if (!success)
11354           return false;
11355 
11356         address = address + 8;
11357         // // Combine the word-aligned words in the correct order for current
11358         // endianness.
11359         // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11360         uint64_t data;
11361         if (GetByteOrder() == eByteOrderBig) {
11362           data = word1;
11363           data = (data << 32) | word2;
11364         } else {
11365           data = word2;
11366           data = (data << 32) | word1;
11367         }
11368 
11369         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11370                                    start_reg + d + r, data))
11371           return false;
11372       }
11373     }
11374   }
11375   return true;
11376 }
11377 
11378 // A8.6.399 VSTM
11379 // Vector Store Multiple stores multiple extension registers to consecutive
11380 // memory locations using an address from an
11381 // ARM core register.
11382 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11383                                         const ARMEncoding encoding) {
11384 #if 0
11385     if ConditionPassed() then
11386         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11387         address = if add then R[n] else R[n]-imm32;
11388         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11389         for r = 0 to regs-1
11390             if single_regs then
11391                 MemA[address,4] = S[d+r]; address = address+4;
11392             else
11393                 // Store as two word-aligned words in the correct order for
11394                 // current endianness.
11395                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11396                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11397                 address = address+8;
11398 #endif
11399 
11400   bool success = false;
11401 
11402   if (ConditionPassed(opcode)) {
11403     bool single_regs;
11404     bool add;
11405     bool wback;
11406     uint32_t d;
11407     uint32_t n;
11408     uint32_t imm32;
11409     uint32_t regs;
11410 
11411     switch (encoding) {
11412     case eEncodingT1:
11413     case eEncodingA1:
11414       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11415       // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11416       // if P == '1' && W == '0' then SEE VSTR;
11417       // if P == U && W == '1' then UNDEFINED;
11418       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11419         return false;
11420 
11421       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11422       // !), 101 (DB with !)
11423       // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11424       single_regs = false;
11425       add = BitIsSet(opcode, 23);
11426       wback = BitIsSet(opcode, 21);
11427 
11428       // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11429       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11430       n = Bits32(opcode, 19, 16);
11431       imm32 = Bits32(opcode, 7, 0) << 2;
11432 
11433       // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11434       regs = Bits32(opcode, 7, 0) / 2;
11435 
11436       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11437       // UNPREDICTABLE;
11438       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11439         return false;
11440 
11441       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11442       if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11443         return false;
11444 
11445       break;
11446 
11447     case eEncodingT2:
11448     case eEncodingA2:
11449       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11450       // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11451       // if P == '1' && W == '0' then SEE VSTR;
11452       // if P == U && W == '1' then UNDEFINED;
11453       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11454         return false;
11455 
11456       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11457       // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11458       // == '1'); d =
11459       // UInt(Vd:D); n = UInt(Rn);
11460       single_regs = true;
11461       add = BitIsSet(opcode, 23);
11462       wback = BitIsSet(opcode, 21);
11463       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11464       n = Bits32(opcode, 19, 16);
11465 
11466       // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11467       imm32 = Bits32(opcode, 7, 0) << 2;
11468       regs = Bits32(opcode, 7, 0);
11469 
11470       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11471       // UNPREDICTABLE;
11472       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11473         return false;
11474 
11475       // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11476       if ((regs == 0) || ((d + regs) > 32))
11477         return false;
11478 
11479       break;
11480 
11481     default:
11482       return false;
11483     }
11484 
11485     std::optional<RegisterInfo> base_reg =
11486         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11487 
11488     uint32_t Rn = ReadCoreReg(n, &success);
11489     if (!success)
11490       return false;
11491 
11492     // address = if add then R[n] else R[n]-imm32;
11493     addr_t address;
11494     if (add)
11495       address = Rn;
11496     else
11497       address = Rn - imm32;
11498 
11499     EmulateInstruction::Context context;
11500     // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11501     if (wback) {
11502       uint32_t value;
11503       if (add)
11504         value = Rn + imm32;
11505       else
11506         value = Rn - imm32;
11507 
11508       context.type = eContextAdjustBaseRegister;
11509       context.SetRegisterPlusOffset(*base_reg, value - Rn);
11510 
11511       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11512                                  value))
11513         return false;
11514     }
11515 
11516     const uint32_t addr_byte_size = GetAddressByteSize();
11517     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11518 
11519     context.type = eContextRegisterStore;
11520     // for r = 0 to regs-1
11521     for (uint32_t r = 0; r < regs; ++r) {
11522 
11523       if (single_regs) {
11524         // MemA[address,4] = S[d+r]; address = address+4;
11525         uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11526                                              start_reg + d + r, 0, &success);
11527         if (!success)
11528           return false;
11529 
11530         std::optional<RegisterInfo> data_reg =
11531             GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r);
11532         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11533                                                 address - Rn);
11534         if (!MemAWrite(context, address, data, addr_byte_size))
11535           return false;
11536 
11537         address = address + 4;
11538       } else {
11539         // // Store as two word-aligned words in the correct order for current
11540         // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11541         // D[d+r]<31:0>;
11542         // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11543         // D[d+r]<63:32>;
11544         uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11545                                              start_reg + d + r, 0, &success);
11546         if (!success)
11547           return false;
11548 
11549         std::optional<RegisterInfo> data_reg =
11550             GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r);
11551 
11552         if (GetByteOrder() == eByteOrderBig) {
11553           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11554                                                   address - Rn);
11555           if (!MemAWrite(context, address, Bits64(data, 63, 32),
11556                          addr_byte_size))
11557             return false;
11558 
11559           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11560                                                   (address + 4) - Rn);
11561           if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11562                          addr_byte_size))
11563             return false;
11564         } else {
11565           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11566                                                   address - Rn);
11567           if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11568             return false;
11569 
11570           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11571                                                   (address + 4) - Rn);
11572           if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11573                          addr_byte_size))
11574             return false;
11575         }
11576         // address = address+8;
11577         address = address + 8;
11578       }
11579     }
11580   }
11581   return true;
11582 }
11583 
11584 // A8.6.320
11585 // This instruction loads a single extension register from memory, using an
11586 // address from an ARM core register, with an optional offset.
11587 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11588                                         ARMEncoding encoding) {
11589 #if 0
11590     if ConditionPassed() then
11591         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11592         base = if n == 15 then Align(PC,4) else R[n];
11593         address = if add then (base + imm32) else (base - imm32);
11594         if single_reg then
11595             S[d] = MemA[address,4];
11596         else
11597             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11598             // Combine the word-aligned words in the correct order for current
11599             // endianness.
11600             D[d] = if BigEndian() then word1:word2 else word2:word1;
11601 #endif
11602 
11603   bool success = false;
11604 
11605   if (ConditionPassed(opcode)) {
11606     bool single_reg;
11607     bool add;
11608     uint32_t imm32;
11609     uint32_t d;
11610     uint32_t n;
11611 
11612     switch (encoding) {
11613     case eEncodingT1:
11614     case eEncodingA1:
11615       // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11616       // 32);
11617       single_reg = false;
11618       add = BitIsSet(opcode, 23);
11619       imm32 = Bits32(opcode, 7, 0) << 2;
11620 
11621       // d = UInt(D:Vd); n = UInt(Rn);
11622       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11623       n = Bits32(opcode, 19, 16);
11624 
11625       break;
11626 
11627     case eEncodingT2:
11628     case eEncodingA2:
11629       // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11630       single_reg = true;
11631       add = BitIsSet(opcode, 23);
11632       imm32 = Bits32(opcode, 7, 0) << 2;
11633 
11634       // d = UInt(Vd:D); n = UInt(Rn);
11635       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11636       n = Bits32(opcode, 19, 16);
11637 
11638       break;
11639 
11640     default:
11641       return false;
11642     }
11643     std::optional<RegisterInfo> base_reg =
11644         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11645 
11646     uint32_t Rn = ReadCoreReg(n, &success);
11647     if (!success)
11648       return false;
11649 
11650     // base = if n == 15 then Align(PC,4) else R[n];
11651     uint32_t base;
11652     if (n == 15)
11653       base = AlignPC(Rn);
11654     else
11655       base = Rn;
11656 
11657     // address = if add then (base + imm32) else (base - imm32);
11658     addr_t address;
11659     if (add)
11660       address = base + imm32;
11661     else
11662       address = base - imm32;
11663 
11664     const uint32_t addr_byte_size = GetAddressByteSize();
11665     uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11666 
11667     EmulateInstruction::Context context;
11668     context.type = eContextRegisterLoad;
11669     context.SetRegisterPlusOffset(*base_reg, address - base);
11670 
11671     if (single_reg) {
11672       // S[d] = MemA[address,4];
11673       uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11674       if (!success)
11675         return false;
11676 
11677       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11678                                  data))
11679         return false;
11680     } else {
11681       // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11682       uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11683       if (!success)
11684         return false;
11685 
11686       context.SetRegisterPlusOffset(*base_reg, (address + 4) - base);
11687       uint32_t word2 =
11688           MemARead(context, address + 4, addr_byte_size, 0, &success);
11689       if (!success)
11690         return false;
11691       // // Combine the word-aligned words in the correct order for current
11692       // endianness.
11693       // D[d] = if BigEndian() then word1:word2 else word2:word1;
11694       uint64_t data64;
11695       if (GetByteOrder() == eByteOrderBig) {
11696         data64 = word1;
11697         data64 = (data64 << 32) | word2;
11698       } else {
11699         data64 = word2;
11700         data64 = (data64 << 32) | word1;
11701       }
11702 
11703       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11704                                  data64))
11705         return false;
11706     }
11707   }
11708   return true;
11709 }
11710 
11711 // A8.6.400 VSTR
11712 // This instruction stores a signle extension register to memory, using an
11713 // address from an ARM core register, with an optional offset.
11714 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11715                                         ARMEncoding encoding) {
11716 #if 0
11717     if ConditionPassed() then
11718         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11719         address = if add then (R[n] + imm32) else (R[n] - imm32);
11720         if single_reg then
11721             MemA[address,4] = S[d];
11722         else
11723             // Store as two word-aligned words in the correct order for current
11724             // endianness.
11725             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11726             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11727 #endif
11728 
11729   bool success = false;
11730 
11731   if (ConditionPassed(opcode)) {
11732     bool single_reg;
11733     bool add;
11734     uint32_t imm32;
11735     uint32_t d;
11736     uint32_t n;
11737 
11738     switch (encoding) {
11739     case eEncodingT1:
11740     case eEncodingA1:
11741       // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11742       // 32);
11743       single_reg = false;
11744       add = BitIsSet(opcode, 23);
11745       imm32 = Bits32(opcode, 7, 0) << 2;
11746 
11747       // d = UInt(D:Vd); n = UInt(Rn);
11748       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11749       n = Bits32(opcode, 19, 16);
11750 
11751       // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11752       if ((n == 15) && (CurrentInstrSet() != eModeARM))
11753         return false;
11754 
11755       break;
11756 
11757     case eEncodingT2:
11758     case eEncodingA2:
11759       // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11760       single_reg = true;
11761       add = BitIsSet(opcode, 23);
11762       imm32 = Bits32(opcode, 7, 0) << 2;
11763 
11764       // d = UInt(Vd:D); n = UInt(Rn);
11765       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11766       n = Bits32(opcode, 19, 16);
11767 
11768       // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11769       if ((n == 15) && (CurrentInstrSet() != eModeARM))
11770         return false;
11771 
11772       break;
11773 
11774     default:
11775       return false;
11776     }
11777 
11778     uint32_t Rn = ReadCoreReg(n, &success);
11779     if (!success)
11780       return false;
11781 
11782     // address = if add then (R[n] + imm32) else (R[n] - imm32);
11783     addr_t address;
11784     if (add)
11785       address = Rn + imm32;
11786     else
11787       address = Rn - imm32;
11788 
11789     const uint32_t addr_byte_size = GetAddressByteSize();
11790     uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11791 
11792     std::optional<RegisterInfo> base_reg =
11793         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11794     std::optional<RegisterInfo> data_reg =
11795         GetRegisterInfo(eRegisterKindDWARF, start_reg + d);
11796     EmulateInstruction::Context context;
11797     context.type = eContextRegisterStore;
11798     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
11799 
11800     if (single_reg) {
11801       // MemA[address,4] = S[d];
11802       uint32_t data =
11803           ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11804       if (!success)
11805         return false;
11806 
11807       if (!MemAWrite(context, address, data, addr_byte_size))
11808         return false;
11809     } else {
11810       // // Store as two word-aligned words in the correct order for current
11811       // endianness.
11812       // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11813       // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11814       uint64_t data =
11815           ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11816       if (!success)
11817         return false;
11818 
11819       if (GetByteOrder() == eByteOrderBig) {
11820         if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11821           return false;
11822 
11823         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11824                                                 (address + 4) - Rn);
11825         if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11826                        addr_byte_size))
11827           return false;
11828       } else {
11829         if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11830           return false;
11831 
11832         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11833                                                 (address + 4) - Rn);
11834         if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11835                        addr_byte_size))
11836           return false;
11837       }
11838     }
11839   }
11840   return true;
11841 }
11842 
11843 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11844 // from memory into one, two, three or four registers, without de-interleaving.
11845 // Every element of each register is loaded.
11846 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11847                                                 ARMEncoding encoding) {
11848 #if 0
11849     if ConditionPassed() then
11850         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11851         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11852         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11853         for r = 0 to regs-1
11854             for e = 0 to elements-1
11855                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11856                 address = address + ebytes;
11857 #endif
11858 
11859   bool success = false;
11860 
11861   if (ConditionPassed(opcode)) {
11862     uint32_t regs;
11863     uint32_t alignment;
11864     uint32_t ebytes;
11865     uint32_t esize;
11866     uint32_t elements;
11867     uint32_t d;
11868     uint32_t n;
11869     uint32_t m;
11870     bool wback;
11871     bool register_index;
11872 
11873     switch (encoding) {
11874     case eEncodingT1:
11875     case eEncodingA1: {
11876       // case type of
11877       // when '0111'
11878       // regs = 1; if align<1> == '1' then UNDEFINED;
11879       // when '1010'
11880       // regs = 2; if align == '11' then UNDEFINED;
11881       // when '0110'
11882       // regs = 3; if align<1> == '1' then UNDEFINED;
11883       // when '0010'
11884       // regs = 4;
11885       // otherwise
11886       // SEE 'Related encodings';
11887       uint32_t type = Bits32(opcode, 11, 8);
11888       uint32_t align = Bits32(opcode, 5, 4);
11889       if (type == 7) // '0111'
11890       {
11891         regs = 1;
11892         if (BitIsSet(align, 1))
11893           return false;
11894       } else if (type == 10) // '1010'
11895       {
11896         regs = 2;
11897         if (align == 3)
11898           return false;
11899 
11900       } else if (type == 6) // '0110'
11901       {
11902         regs = 3;
11903         if (BitIsSet(align, 1))
11904           return false;
11905       } else if (type == 2) // '0010'
11906       {
11907         regs = 4;
11908       } else
11909         return false;
11910 
11911       // alignment = if align == '00' then 1 else 4 << UInt(align);
11912       if (align == 0)
11913         alignment = 1;
11914       else
11915         alignment = 4 << align;
11916 
11917       // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11918       ebytes = 1 << Bits32(opcode, 7, 6);
11919       esize = 8 * ebytes;
11920       elements = 8 / ebytes;
11921 
11922       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11923       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11924       n = Bits32(opcode, 19, 15);
11925       m = Bits32(opcode, 3, 0);
11926 
11927       // wback = (m != 15); register_index = (m != 15 && m != 13);
11928       wback = (m != 15);
11929       register_index = ((m != 15) && (m != 13));
11930 
11931       // if d+regs > 32 then UNPREDICTABLE;
11932       if ((d + regs) > 32)
11933         return false;
11934     } break;
11935 
11936     default:
11937       return false;
11938     }
11939 
11940     std::optional<RegisterInfo> base_reg =
11941         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11942 
11943     uint32_t Rn = ReadCoreReg(n, &success);
11944     if (!success)
11945       return false;
11946 
11947     // address = R[n]; if (address MOD alignment) != 0 then
11948     // GenerateAlignmentException();
11949     addr_t address = Rn;
11950     if ((address % alignment) != 0)
11951       return false;
11952 
11953     EmulateInstruction::Context context;
11954     // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11955     if (wback) {
11956       uint32_t Rm = ReadCoreReg(m, &success);
11957       if (!success)
11958         return false;
11959 
11960       uint32_t offset;
11961       if (register_index)
11962         offset = Rm;
11963       else
11964         offset = 8 * regs;
11965 
11966       uint32_t value = Rn + offset;
11967       context.type = eContextAdjustBaseRegister;
11968       context.SetRegisterPlusOffset(*base_reg, offset);
11969 
11970       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11971                                  value))
11972         return false;
11973     }
11974 
11975     // for r = 0 to regs-1
11976     for (uint32_t r = 0; r < regs; ++r) {
11977       // for e = 0 to elements-1
11978       uint64_t assembled_data = 0;
11979       for (uint32_t e = 0; e < elements; ++e) {
11980         // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11981         context.type = eContextRegisterLoad;
11982         context.SetRegisterPlusOffset(*base_reg, address - Rn);
11983         uint64_t data = MemURead(context, address, ebytes, 0, &success);
11984         if (!success)
11985           return false;
11986 
11987         assembled_data =
11988             (data << (e * esize)) |
11989             assembled_data; // New data goes to the left of existing data
11990 
11991         // address = address + ebytes;
11992         address = address + ebytes;
11993       }
11994       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
11995                                  assembled_data))
11996         return false;
11997     }
11998   }
11999   return true;
12000 }
12001 
12002 // A8.6.308 VLD1 (single element to one lane)
12003 //
12004 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12005                                               const ARMEncoding encoding) {
12006 #if 0
12007     if ConditionPassed() then
12008         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12009         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12010         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12011         Elem[D[d],index,esize] = MemU[address,ebytes];
12012 #endif
12013 
12014   bool success = false;
12015 
12016   if (ConditionPassed(opcode)) {
12017     uint32_t ebytes;
12018     uint32_t esize;
12019     uint32_t index;
12020     uint32_t alignment;
12021     uint32_t d;
12022     uint32_t n;
12023     uint32_t m;
12024     bool wback;
12025     bool register_index;
12026 
12027     switch (encoding) {
12028     case eEncodingT1:
12029     case eEncodingA1: {
12030       uint32_t size = Bits32(opcode, 11, 10);
12031       uint32_t index_align = Bits32(opcode, 7, 4);
12032       // if size == '11' then SEE VLD1 (single element to all lanes);
12033       if (size == 3)
12034         return EmulateVLD1SingleAll(opcode, encoding);
12035       // case size of
12036       if (size == 0) // when '00'
12037       {
12038         // if index_align<0> != '0' then UNDEFINED;
12039         if (BitIsClear(index_align, 0))
12040           return false;
12041 
12042         // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12043         ebytes = 1;
12044         esize = 8;
12045         index = Bits32(index_align, 3, 1);
12046         alignment = 1;
12047       } else if (size == 1) // when '01'
12048       {
12049         // if index_align<1> != '0' then UNDEFINED;
12050         if (BitIsClear(index_align, 1))
12051           return false;
12052 
12053         // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12054         ebytes = 2;
12055         esize = 16;
12056         index = Bits32(index_align, 3, 2);
12057 
12058         // alignment = if index_align<0> == '0' then 1 else 2;
12059         if (BitIsClear(index_align, 0))
12060           alignment = 1;
12061         else
12062           alignment = 2;
12063       } else if (size == 2) // when '10'
12064       {
12065         // if index_align<2> != '0' then UNDEFINED;
12066         if (BitIsClear(index_align, 2))
12067           return false;
12068 
12069         // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12070         // UNDEFINED;
12071         if ((Bits32(index_align, 1, 0) != 0) &&
12072             (Bits32(index_align, 1, 0) != 3))
12073           return false;
12074 
12075         // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12076         ebytes = 4;
12077         esize = 32;
12078         index = Bit32(index_align, 3);
12079 
12080         // alignment = if index_align<1:0> == '00' then 1 else 4;
12081         if (Bits32(index_align, 1, 0) == 0)
12082           alignment = 1;
12083         else
12084           alignment = 4;
12085       } else {
12086         return false;
12087       }
12088       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12089       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12090       n = Bits32(opcode, 19, 16);
12091       m = Bits32(opcode, 3, 0);
12092 
12093       // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12094       // then UNPREDICTABLE;
12095       wback = (m != 15);
12096       register_index = ((m != 15) && (m != 13));
12097 
12098       if (n == 15)
12099         return false;
12100 
12101     } break;
12102 
12103     default:
12104       return false;
12105     }
12106 
12107     uint32_t Rn = ReadCoreReg(n, &success);
12108     if (!success)
12109       return false;
12110 
12111     // address = R[n]; if (address MOD alignment) != 0 then
12112     // GenerateAlignmentException();
12113     addr_t address = Rn;
12114     if ((address % alignment) != 0)
12115       return false;
12116 
12117     EmulateInstruction::Context context;
12118     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12119     if (wback) {
12120       uint32_t Rm = ReadCoreReg(m, &success);
12121       if (!success)
12122         return false;
12123 
12124       uint32_t offset;
12125       if (register_index)
12126         offset = Rm;
12127       else
12128         offset = ebytes;
12129 
12130       uint32_t value = Rn + offset;
12131 
12132       context.type = eContextAdjustBaseRegister;
12133       std::optional<RegisterInfo> base_reg =
12134           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12135       context.SetRegisterPlusOffset(*base_reg, offset);
12136 
12137       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12138                                  value))
12139         return false;
12140     }
12141 
12142     // Elem[D[d],index,esize] = MemU[address,ebytes];
12143     uint32_t element = MemURead(context, address, esize, 0, &success);
12144     if (!success)
12145       return false;
12146 
12147     element = element << (index * esize);
12148 
12149     uint64_t reg_data =
12150         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12151     if (!success)
12152       return false;
12153 
12154     uint64_t all_ones = -1;
12155     uint64_t mask = all_ones
12156                     << ((index + 1) * esize); // mask is all 1's to left of
12157                                               // where 'element' goes, & all 0's
12158     // at element & to the right of element.
12159     if (index > 0)
12160       mask = mask | Bits64(all_ones, (index * esize) - 1,
12161                            0); // add 1's to the right of where 'element' goes.
12162     // now mask should be 0's where element goes & 1's everywhere else.
12163 
12164     uint64_t masked_reg =
12165         reg_data & mask; // Take original reg value & zero out 'element' bits
12166     reg_data =
12167         masked_reg & element; // Put 'element' into those bits in reg_data.
12168 
12169     context.type = eContextRegisterLoad;
12170     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12171                                reg_data))
12172       return false;
12173   }
12174   return true;
12175 }
12176 
12177 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12178 // elements) stores elements to memory from one, two, three, or four registers,
12179 // without interleaving.  Every element of each register is stored.
12180 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12181                                                 ARMEncoding encoding) {
12182 #if 0
12183     if ConditionPassed() then
12184         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12185         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12186         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12187         for r = 0 to regs-1
12188             for e = 0 to elements-1
12189                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12190                 address = address + ebytes;
12191 #endif
12192 
12193   bool success = false;
12194 
12195   if (ConditionPassed(opcode)) {
12196     uint32_t regs;
12197     uint32_t alignment;
12198     uint32_t ebytes;
12199     uint32_t esize;
12200     uint32_t elements;
12201     uint32_t d;
12202     uint32_t n;
12203     uint32_t m;
12204     bool wback;
12205     bool register_index;
12206 
12207     switch (encoding) {
12208     case eEncodingT1:
12209     case eEncodingA1: {
12210       uint32_t type = Bits32(opcode, 11, 8);
12211       uint32_t align = Bits32(opcode, 5, 4);
12212 
12213       // case type of
12214       if (type == 7) // when '0111'
12215       {
12216         // regs = 1; if align<1> == '1' then UNDEFINED;
12217         regs = 1;
12218         if (BitIsSet(align, 1))
12219           return false;
12220       } else if (type == 10) // when '1010'
12221       {
12222         // regs = 2; if align == '11' then UNDEFINED;
12223         regs = 2;
12224         if (align == 3)
12225           return false;
12226       } else if (type == 6) // when '0110'
12227       {
12228         // regs = 3; if align<1> == '1' then UNDEFINED;
12229         regs = 3;
12230         if (BitIsSet(align, 1))
12231           return false;
12232       } else if (type == 2) // when '0010'
12233         // regs = 4;
12234         regs = 4;
12235       else // otherwise
12236         // SEE 'Related encodings';
12237         return false;
12238 
12239       // alignment = if align == '00' then 1 else 4 << UInt(align);
12240       if (align == 0)
12241         alignment = 1;
12242       else
12243         alignment = 4 << align;
12244 
12245       // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12246       ebytes = 1 << Bits32(opcode, 7, 6);
12247       esize = 8 * ebytes;
12248       elements = 8 / ebytes;
12249 
12250       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12251       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12252       n = Bits32(opcode, 19, 16);
12253       m = Bits32(opcode, 3, 0);
12254 
12255       // wback = (m != 15); register_index = (m != 15 && m != 13);
12256       wback = (m != 15);
12257       register_index = ((m != 15) && (m != 13));
12258 
12259       // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12260       if ((d + regs) > 32)
12261         return false;
12262 
12263       if (n == 15)
12264         return false;
12265 
12266     } break;
12267 
12268     default:
12269       return false;
12270     }
12271 
12272     std::optional<RegisterInfo> base_reg =
12273         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12274 
12275     uint32_t Rn = ReadCoreReg(n, &success);
12276     if (!success)
12277       return false;
12278 
12279     // address = R[n]; if (address MOD alignment) != 0 then
12280     // GenerateAlignmentException();
12281     addr_t address = Rn;
12282     if ((address % alignment) != 0)
12283       return false;
12284 
12285     EmulateInstruction::Context context;
12286     // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12287     if (wback) {
12288       uint32_t Rm = ReadCoreReg(m, &success);
12289       if (!success)
12290         return false;
12291 
12292       uint32_t offset;
12293       if (register_index)
12294         offset = Rm;
12295       else
12296         offset = 8 * regs;
12297 
12298       context.type = eContextAdjustBaseRegister;
12299       context.SetRegisterPlusOffset(*base_reg, offset);
12300 
12301       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12302                                  Rn + offset))
12303         return false;
12304     }
12305 
12306     context.type = eContextRegisterStore;
12307     // for r = 0 to regs-1
12308     for (uint32_t r = 0; r < regs; ++r) {
12309       std::optional<RegisterInfo> data_reg =
12310           GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r);
12311       uint64_t register_data = ReadRegisterUnsigned(
12312           eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12313       if (!success)
12314         return false;
12315 
12316       // for e = 0 to elements-1
12317       for (uint32_t e = 0; e < elements; ++e) {
12318         // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12319         uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12320 
12321         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
12322                                                 address - Rn);
12323         if (!MemUWrite(context, address, word, ebytes))
12324           return false;
12325 
12326         // address = address + ebytes;
12327         address = address + ebytes;
12328       }
12329     }
12330   }
12331   return true;
12332 }
12333 
12334 // A8.6.392 VST1 (single element from one lane) This instruction stores one
12335 // element to memory from one element of a register.
12336 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12337                                               ARMEncoding encoding) {
12338 #if 0
12339     if ConditionPassed() then
12340         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12341         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12342         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12343         MemU[address,ebytes] = Elem[D[d],index,esize];
12344 #endif
12345 
12346   bool success = false;
12347 
12348   if (ConditionPassed(opcode)) {
12349     uint32_t ebytes;
12350     uint32_t esize;
12351     uint32_t index;
12352     uint32_t alignment;
12353     uint32_t d;
12354     uint32_t n;
12355     uint32_t m;
12356     bool wback;
12357     bool register_index;
12358 
12359     switch (encoding) {
12360     case eEncodingT1:
12361     case eEncodingA1: {
12362       uint32_t size = Bits32(opcode, 11, 10);
12363       uint32_t index_align = Bits32(opcode, 7, 4);
12364 
12365       // if size == '11' then UNDEFINED;
12366       if (size == 3)
12367         return false;
12368 
12369       // case size of
12370       if (size == 0) // when '00'
12371       {
12372         // if index_align<0> != '0' then UNDEFINED;
12373         if (BitIsClear(index_align, 0))
12374           return false;
12375         // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12376         ebytes = 1;
12377         esize = 8;
12378         index = Bits32(index_align, 3, 1);
12379         alignment = 1;
12380       } else if (size == 1) // when '01'
12381       {
12382         // if index_align<1> != '0' then UNDEFINED;
12383         if (BitIsClear(index_align, 1))
12384           return false;
12385 
12386         // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12387         ebytes = 2;
12388         esize = 16;
12389         index = Bits32(index_align, 3, 2);
12390 
12391         // alignment = if index_align<0> == '0' then 1 else 2;
12392         if (BitIsClear(index_align, 0))
12393           alignment = 1;
12394         else
12395           alignment = 2;
12396       } else if (size == 2) // when '10'
12397       {
12398         // if index_align<2> != '0' then UNDEFINED;
12399         if (BitIsClear(index_align, 2))
12400           return false;
12401 
12402         // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12403         // UNDEFINED;
12404         if ((Bits32(index_align, 1, 0) != 0) &&
12405             (Bits32(index_align, 1, 0) != 3))
12406           return false;
12407 
12408         // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12409         ebytes = 4;
12410         esize = 32;
12411         index = Bit32(index_align, 3);
12412 
12413         // alignment = if index_align<1:0> == '00' then 1 else 4;
12414         if (Bits32(index_align, 1, 0) == 0)
12415           alignment = 1;
12416         else
12417           alignment = 4;
12418       } else {
12419         return false;
12420       }
12421       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12422       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12423       n = Bits32(opcode, 19, 16);
12424       m = Bits32(opcode, 3, 0);
12425 
12426       // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12427       // then UNPREDICTABLE;
12428       wback = (m != 15);
12429       register_index = ((m != 15) && (m != 13));
12430 
12431       if (n == 15)
12432         return false;
12433     } break;
12434 
12435     default:
12436       return false;
12437     }
12438 
12439     std::optional<RegisterInfo> base_reg =
12440         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12441 
12442     uint32_t Rn = ReadCoreReg(n, &success);
12443     if (!success)
12444       return false;
12445 
12446     // address = R[n]; if (address MOD alignment) != 0 then
12447     // GenerateAlignmentException();
12448     addr_t address = Rn;
12449     if ((address % alignment) != 0)
12450       return false;
12451 
12452     EmulateInstruction::Context context;
12453     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12454     if (wback) {
12455       uint32_t Rm = ReadCoreReg(m, &success);
12456       if (!success)
12457         return false;
12458 
12459       uint32_t offset;
12460       if (register_index)
12461         offset = Rm;
12462       else
12463         offset = ebytes;
12464 
12465       context.type = eContextAdjustBaseRegister;
12466       context.SetRegisterPlusOffset(*base_reg, offset);
12467 
12468       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12469                                  Rn + offset))
12470         return false;
12471     }
12472 
12473     // MemU[address,ebytes] = Elem[D[d],index,esize];
12474     uint64_t register_data =
12475         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12476     if (!success)
12477       return false;
12478 
12479     uint64_t word =
12480         Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12481 
12482     std::optional<RegisterInfo> data_reg =
12483         GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d);
12484     context.type = eContextRegisterStore;
12485     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
12486 
12487     if (!MemUWrite(context, address, word, ebytes))
12488       return false;
12489   }
12490   return true;
12491 }
12492 
12493 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12494 // element from memory into every element of one or two vectors.
12495 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12496                                                  const ARMEncoding encoding) {
12497 #if 0
12498     if ConditionPassed() then
12499         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12500         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12501         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12502         replicated_element = Replicate(MemU[address,ebytes], elements);
12503         for r = 0 to regs-1
12504             D[d+r] = replicated_element;
12505 #endif
12506 
12507   bool success = false;
12508 
12509   if (ConditionPassed(opcode)) {
12510     uint32_t ebytes;
12511     uint32_t elements;
12512     uint32_t regs;
12513     uint32_t alignment;
12514     uint32_t d;
12515     uint32_t n;
12516     uint32_t m;
12517     bool wback;
12518     bool register_index;
12519 
12520     switch (encoding) {
12521     case eEncodingT1:
12522     case eEncodingA1: {
12523       // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12524       uint32_t size = Bits32(opcode, 7, 6);
12525       if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12526         return false;
12527 
12528       // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12529       // then 1 else 2;
12530       ebytes = 1 << size;
12531       elements = 8 / ebytes;
12532       if (BitIsClear(opcode, 5))
12533         regs = 1;
12534       else
12535         regs = 2;
12536 
12537       // alignment = if a == '0' then 1 else ebytes;
12538       if (BitIsClear(opcode, 4))
12539         alignment = 1;
12540       else
12541         alignment = ebytes;
12542 
12543       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12544       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12545       n = Bits32(opcode, 19, 16);
12546       m = Bits32(opcode, 3, 0);
12547 
12548       // wback = (m != 15); register_index = (m != 15 && m != 13);
12549       wback = (m != 15);
12550       register_index = ((m != 15) && (m != 13));
12551 
12552       // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12553       if ((d + regs) > 32)
12554         return false;
12555 
12556       if (n == 15)
12557         return false;
12558     } break;
12559 
12560     default:
12561       return false;
12562     }
12563 
12564     uint32_t Rn = ReadCoreReg(n, &success);
12565     if (!success)
12566       return false;
12567 
12568     // address = R[n]; if (address MOD alignment) != 0 then
12569     // GenerateAlignmentException();
12570     addr_t address = Rn;
12571     if ((address % alignment) != 0)
12572       return false;
12573 
12574     EmulateInstruction::Context context;
12575     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12576     if (wback) {
12577       uint32_t Rm = ReadCoreReg(m, &success);
12578       if (!success)
12579         return false;
12580 
12581       uint32_t offset;
12582       if (register_index)
12583         offset = Rm;
12584       else
12585         offset = ebytes;
12586 
12587       context.type = eContextAdjustBaseRegister;
12588       std::optional<RegisterInfo> base_reg =
12589           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12590       context.SetRegisterPlusOffset(*base_reg, offset);
12591 
12592       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12593                                  Rn + offset))
12594         return false;
12595     }
12596 
12597     // replicated_element = Replicate(MemU[address,ebytes], elements);
12598 
12599     context.type = eContextRegisterLoad;
12600     uint64_t word = MemURead(context, address, ebytes, 0, &success);
12601     if (!success)
12602       return false;
12603 
12604     uint64_t replicated_element = 0;
12605     uint32_t esize = ebytes * 8;
12606     for (uint32_t e = 0; e < elements; ++e)
12607       replicated_element =
12608           (replicated_element << esize) | Bits64(word, esize - 1, 0);
12609 
12610     // for r = 0 to regs-1
12611     for (uint32_t r = 0; r < regs; ++r) {
12612       // D[d+r] = replicated_element;
12613       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12614                                  replicated_element))
12615         return false;
12616     }
12617   }
12618   return true;
12619 }
12620 
12621 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12622 // instruction provides an exception return without the use of the stack.  It
12623 // subtracts the immediate constant from the LR, branches to the resulting
12624 // address, and also copies the SPSR to the CPSR.
12625 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12626                                                const ARMEncoding encoding) {
12627 #if 0
12628     if ConditionPassed() then
12629         EncodingSpecificOperations();
12630         if CurrentInstrSet() == InstrSet_ThumbEE then
12631             UNPREDICTABLE;
12632         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12633         case opcode of
12634             when '0000' result = R[n] AND operand2; // AND
12635             when '0001' result = R[n] EOR operand2; // EOR
12636             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12637             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12638             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12639             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12640             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12641             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12642             when '1100' result = R[n] OR operand2; // ORR
12643             when '1101' result = operand2; // MOV
12644             when '1110' result = R[n] AND NOT(operand2); // BIC
12645             when '1111' result = NOT(operand2); // MVN
12646         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12647         BranchWritePC(result);
12648 #endif
12649 
12650   bool success = false;
12651 
12652   if (ConditionPassed(opcode)) {
12653     uint32_t n;
12654     uint32_t m;
12655     uint32_t imm32;
12656     bool register_form;
12657     ARM_ShifterType shift_t;
12658     uint32_t shift_n;
12659     uint32_t code;
12660 
12661     switch (encoding) {
12662     case eEncodingT1:
12663       // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12664       // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12665       // // = SUB
12666       n = 14;
12667       imm32 = Bits32(opcode, 7, 0);
12668       register_form = false;
12669       code = 2;
12670 
12671       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12672       if (InITBlock() && !LastInITBlock())
12673         return false;
12674 
12675       break;
12676 
12677     case eEncodingA1:
12678       // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12679       n = Bits32(opcode, 19, 16);
12680       imm32 = ARMExpandImm(opcode);
12681       register_form = false;
12682       code = Bits32(opcode, 24, 21);
12683 
12684       break;
12685 
12686     case eEncodingA2:
12687       // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12688       n = Bits32(opcode, 19, 16);
12689       m = Bits32(opcode, 3, 0);
12690       register_form = true;
12691 
12692       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12693       shift_n = DecodeImmShiftARM(opcode, shift_t);
12694 
12695       break;
12696 
12697     default:
12698       return false;
12699     }
12700 
12701     // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12702     // else imm32;
12703     uint32_t operand2;
12704     if (register_form) {
12705       uint32_t Rm = ReadCoreReg(m, &success);
12706       if (!success)
12707         return false;
12708 
12709       operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12710       if (!success)
12711         return false;
12712     } else {
12713       operand2 = imm32;
12714     }
12715 
12716     uint32_t Rn = ReadCoreReg(n, &success);
12717     if (!success)
12718       return false;
12719 
12720     AddWithCarryResult result;
12721 
12722     // case opcode of
12723     switch (code) {
12724     case 0: // when '0000'
12725       // result = R[n] AND operand2; // AND
12726       result.result = Rn & operand2;
12727       break;
12728 
12729     case 1: // when '0001'
12730       // result = R[n] EOR operand2; // EOR
12731       result.result = Rn ^ operand2;
12732       break;
12733 
12734     case 2: // when '0010'
12735       // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12736       result = AddWithCarry(Rn, ~(operand2), 1);
12737       break;
12738 
12739     case 3: // when '0011'
12740       // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12741       result = AddWithCarry(~(Rn), operand2, 1);
12742       break;
12743 
12744     case 4: // when '0100'
12745       // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12746       result = AddWithCarry(Rn, operand2, 0);
12747       break;
12748 
12749     case 5: // when '0101'
12750       // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12751       result = AddWithCarry(Rn, operand2, APSR_C);
12752       break;
12753 
12754     case 6: // when '0110'
12755       // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12756       result = AddWithCarry(Rn, ~(operand2), APSR_C);
12757       break;
12758 
12759     case 7: // when '0111'
12760       // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12761       result = AddWithCarry(~(Rn), operand2, APSR_C);
12762       break;
12763 
12764     case 10: // when '1100'
12765       // result = R[n] OR operand2; // ORR
12766       result.result = Rn | operand2;
12767       break;
12768 
12769     case 11: // when '1101'
12770       // result = operand2; // MOV
12771       result.result = operand2;
12772       break;
12773 
12774     case 12: // when '1110'
12775       // result = R[n] AND NOT(operand2); // BIC
12776       result.result = Rn & ~(operand2);
12777       break;
12778 
12779     case 15: // when '1111'
12780       // result = NOT(operand2); // MVN
12781       result.result = ~(operand2);
12782       break;
12783 
12784     default:
12785       return false;
12786     }
12787     // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12788 
12789     // For now, in emulation mode, we don't have access to the SPSR, so we will
12790     // use the CPSR instead, and hope for the best.
12791     uint32_t spsr =
12792         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12793     if (!success)
12794       return false;
12795 
12796     CPSRWriteByInstr(spsr, 15, true);
12797 
12798     // BranchWritePC(result);
12799     EmulateInstruction::Context context;
12800     context.type = eContextAdjustPC;
12801     context.SetImmediate(result.result);
12802 
12803     BranchWritePC(context, result.result);
12804   }
12805   return true;
12806 }
12807 
12808 EmulateInstructionARM::ARMOpcode *
12809 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12810                                                   uint32_t arm_isa) {
12811   static ARMOpcode g_arm_opcodes[] = {
12812       // Prologue instructions
12813 
12814       // push register(s)
12815       {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12816        &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12817       {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12818        &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12819 
12820       // set r7 to point to a stack offset
12821       {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12822        &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12823       {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12824        &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12825       // copy the stack pointer to ip
12826       {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12827        &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12828       {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12829        &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12830       {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12831        &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12832 
12833       // adjust the stack pointer
12834       {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12835        &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12836       {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12837        &EmulateInstructionARM::EmulateSUBSPReg,
12838        "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12839 
12840       // push one register
12841       // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12842       {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12843        &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12844 
12845       // vector push consecutive extension register(s)
12846       {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12847        &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12848       {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12849        &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12850 
12851       // Epilogue instructions
12852 
12853       {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12854        &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12855       {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12856        &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12857       {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12858        &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12859       {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12860        &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12861 
12862       // Supervisor Call (previously Software Interrupt)
12863       {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12864        &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12865 
12866       // Branch instructions
12867       // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12868       // "bl <label>".
12869       {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12870        &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12871       {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12872        &EmulateInstructionARM::EmulateB, "b #imm24"},
12873       {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12874        &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12875       {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12876        &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12877       // for example, "bx lr"
12878       {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12879        &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12880       // bxj
12881       {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12882        &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12883 
12884       // Data-processing instructions
12885       // adc (immediate)
12886       {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12887        &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12888       // adc (register)
12889       {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12890        &EmulateInstructionARM::EmulateADCReg,
12891        "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12892       // add (immediate)
12893       {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12894        &EmulateInstructionARM::EmulateADDImmARM,
12895        "add{s}<c> <Rd>, <Rn>, #const"},
12896       // add (register)
12897       {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12898        &EmulateInstructionARM::EmulateADDReg,
12899        "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12900       // add (register-shifted register)
12901       {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12902        &EmulateInstructionARM::EmulateADDRegShift,
12903        "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12904       // adr
12905       {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12906        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12907       {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12908        &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12909       // and (immediate)
12910       {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12911        &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12912       // and (register)
12913       {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12914        &EmulateInstructionARM::EmulateANDReg,
12915        "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12916       // bic (immediate)
12917       {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12918        &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12919       // bic (register)
12920       {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12921        &EmulateInstructionARM::EmulateBICReg,
12922        "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12923       // eor (immediate)
12924       {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12925        &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12926       // eor (register)
12927       {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12928        &EmulateInstructionARM::EmulateEORReg,
12929        "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12930       // orr (immediate)
12931       {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12932        &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12933       // orr (register)
12934       {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12935        &EmulateInstructionARM::EmulateORRReg,
12936        "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12937       // rsb (immediate)
12938       {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12939        &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12940       // rsb (register)
12941       {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12942        &EmulateInstructionARM::EmulateRSBReg,
12943        "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12944       // rsc (immediate)
12945       {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12946        &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12947       // rsc (register)
12948       {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12949        &EmulateInstructionARM::EmulateRSCReg,
12950        "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12951       // sbc (immediate)
12952       {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12953        &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12954       // sbc (register)
12955       {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12956        &EmulateInstructionARM::EmulateSBCReg,
12957        "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12958       // sub (immediate, ARM)
12959       {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12960        &EmulateInstructionARM::EmulateSUBImmARM,
12961        "sub{s}<c> <Rd>, <Rn>, #<const>"},
12962       // sub (sp minus immediate)
12963       {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12964        &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12965       // sub (register)
12966       {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12967        &EmulateInstructionARM::EmulateSUBReg,
12968        "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12969       // teq (immediate)
12970       {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12971        &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12972       // teq (register)
12973       {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12974        &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12975       // tst (immediate)
12976       {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12977        &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12978       // tst (register)
12979       {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12980        &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12981 
12982       // mov (immediate)
12983       {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12984        &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12985       {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12986        &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
12987       // mov (register)
12988       {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12989        &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12990       // mvn (immediate)
12991       {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12992        &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12993       // mvn (register)
12994       {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12995        &EmulateInstructionARM::EmulateMVNReg,
12996        "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12997       // cmn (immediate)
12998       {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12999        &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13000       // cmn (register)
13001       {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13002        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13003       // cmp (immediate)
13004       {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13005        &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13006       // cmp (register)
13007       {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13008        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13009       // asr (immediate)
13010       {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13011        &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13012       // asr (register)
13013       {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13014        &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13015       // lsl (immediate)
13016       {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13017        &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13018       // lsl (register)
13019       {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13020        &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13021       // lsr (immediate)
13022       {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13023        &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13024       // lsr (register)
13025       {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13026        &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13027       // rrx is a special case encoding of ror (immediate)
13028       {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13029        &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13030       // ror (immediate)
13031       {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13032        &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13033       // ror (register)
13034       {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13035        &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13036       // mul
13037       {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038        &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13039 
13040       // subs pc, lr and related instructions
13041       {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13042        &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13043        "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13044       {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13045        &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13046        "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13047 
13048       // Load instructions
13049       {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13050        &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13051       {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13052        &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13053       {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13054        &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13055       {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13056        &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13057       {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13058        &EmulateInstructionARM::EmulateLDRImmediateARM,
13059        "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13060       {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13061        &EmulateInstructionARM::EmulateLDRRegister,
13062        "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13063       {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13064        &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13065       {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13066        &EmulateInstructionARM::EmulateLDRBRegister,
13067        "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13068       {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13069        &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13070       {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13071        &EmulateInstructionARM::EmulateLDRHRegister,
13072        "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13073       {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13074        &EmulateInstructionARM::EmulateLDRSBImmediate,
13075        "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13076       {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13077        &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13078       {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13079        &EmulateInstructionARM::EmulateLDRSBRegister,
13080        "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13081       {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13082        &EmulateInstructionARM::EmulateLDRSHImmediate,
13083        "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13084       {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13085        &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13086       {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13087        &EmulateInstructionARM::EmulateLDRSHRegister,
13088        "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13089       {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13090        &EmulateInstructionARM::EmulateLDRDImmediate,
13091        "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13092       {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13093        &EmulateInstructionARM::EmulateLDRDRegister,
13094        "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13095       {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13096        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13097       {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13098        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13099       {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13100        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13101       {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13102        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13103       {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13104        &EmulateInstructionARM::EmulateVLD1Multiple,
13105        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13106       {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13107        &EmulateInstructionARM::EmulateVLD1Single,
13108        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13109       {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13110        &EmulateInstructionARM::EmulateVLD1SingleAll,
13111        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13112 
13113       // Store instructions
13114       {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13115        &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13116       {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13117        &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13118       {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13119        &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13120       {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13121        &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13122       {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13123        &EmulateInstructionARM::EmulateSTRRegister,
13124        "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13125       {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13126        &EmulateInstructionARM::EmulateSTRHRegister,
13127        "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13128       {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13129        &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13130       {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13131        &EmulateInstructionARM::EmulateSTRBImmARM,
13132        "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13133       {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13134        &EmulateInstructionARM::EmulateSTRImmARM,
13135        "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13136       {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13137        &EmulateInstructionARM::EmulateSTRDImm,
13138        "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13139       {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13140        &EmulateInstructionARM::EmulateSTRDReg,
13141        "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13142       {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13143        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13144       {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13145        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13146       {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13147        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13148       {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13149        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13150       {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13151        &EmulateInstructionARM::EmulateVST1Multiple,
13152        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13153       {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13154        &EmulateInstructionARM::EmulateVST1Single,
13155        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13156 
13157       // Other instructions
13158       {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13159        &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13160       {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13161        &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13162       {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13163        &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13164       {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13165        &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13166       {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13167        &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13168 
13169   };
13170   static const size_t k_num_arm_opcodes = std::size(g_arm_opcodes);
13171 
13172   for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13173     if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13174         (g_arm_opcodes[i].variants & arm_isa) != 0)
13175       return &g_arm_opcodes[i];
13176   }
13177   return nullptr;
13178 }
13179 
13180 EmulateInstructionARM::ARMOpcode *
13181 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13182                                                     uint32_t arm_isa) {
13183 
13184   static ARMOpcode g_thumb_opcodes[] = {
13185       // Prologue instructions
13186 
13187       // push register(s)
13188       {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13189        &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13190       {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13191        &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13192       {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13193        &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13194 
13195       // set r7 to point to a stack offset
13196       {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13197        &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13198       // copy the stack pointer to r7
13199       {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13200        &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13201       // move from high register to low register (comes after "mov r7, sp" to
13202       // resolve ambiguity)
13203       {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13204        &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13205 
13206       // PC-relative load into register (see also EmulateADDSPRm)
13207       {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13208        &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13209 
13210       // adjust the stack pointer
13211       {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13212        &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13213       {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13214        &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13215       {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13216        &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13217       {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13218        &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13219       {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13220        &EmulateInstructionARM::EmulateSUBSPReg,
13221        "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13222 
13223       // vector push consecutive extension register(s)
13224       {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13225        &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13226       {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13227        &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13228 
13229       // Epilogue instructions
13230 
13231       {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13232        &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13233       {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13234        &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13235       {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13236        &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13237       {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13238        &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13239       {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13240        &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13241       {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13242        &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13243       {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13244        &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13245 
13246       // Supervisor Call (previously Software Interrupt)
13247       {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13248        &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13249 
13250       // If Then makes up to four following instructions conditional.
13251       // The next 5 opcode _must_ come before the if then instruction
13252       {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13253        &EmulateInstructionARM::EmulateNop, "nop"},
13254       {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13255        &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13256       {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13257        &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13258       {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13259        &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13260       {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13261        &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13262       {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13263        &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13264 
13265       // Branch instructions
13266       // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13267       {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13268        &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13269       {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13270        &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13271       {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13272        &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13273       {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13274        &EmulateInstructionARM::EmulateB,
13275        "b<c>.w #imm8 (outside or last in IT)"},
13276       // J1 == J2 == 1
13277       {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13278        &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13279       // J1 == J2 == 1
13280       {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13281        &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13282       {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13283        &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13284       // for example, "bx lr"
13285       {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13286        &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13287       // bxj
13288       {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13289        &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13290       // compare and branch
13291       {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13292        &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13293       // table branch byte
13294       {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13295        &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13296       // table branch halfword
13297       {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13298        &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13299 
13300       // Data-processing instructions
13301       // adc (immediate)
13302       {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13303        &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13304       // adc (register)
13305       {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13306        &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13307       {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13308        &EmulateInstructionARM::EmulateADCReg,
13309        "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13310       // add (register)
13311       {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13312        &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13313       // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13314       // ambiguity decoding the two.
13315       {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13316        &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13317       // adr
13318       {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13319        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13320       {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13321        &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13322       {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13323        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13324       // and (immediate)
13325       {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13326        &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13327       // and (register)
13328       {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13329        &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13330       {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13331        &EmulateInstructionARM::EmulateANDReg,
13332        "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13333       // bic (immediate)
13334       {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13335        &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13336       // bic (register)
13337       {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13338        &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13339       {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13340        &EmulateInstructionARM::EmulateBICReg,
13341        "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13342       // eor (immediate)
13343       {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13344        &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13345       // eor (register)
13346       {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13347        &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13348       {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13349        &EmulateInstructionARM::EmulateEORReg,
13350        "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13351       // orr (immediate)
13352       {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13353        &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13354       // orr (register)
13355       {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13356        &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13357       {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13358        &EmulateInstructionARM::EmulateORRReg,
13359        "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13360       // rsb (immediate)
13361       {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13362        &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13363       {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13364        &EmulateInstructionARM::EmulateRSBImm,
13365        "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13366       // rsb (register)
13367       {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13368        &EmulateInstructionARM::EmulateRSBReg,
13369        "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13370       // sbc (immediate)
13371       {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13372        &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13373       // sbc (register)
13374       {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13375        &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13376       {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13377        &EmulateInstructionARM::EmulateSBCReg,
13378        "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13379       // add (immediate, Thumb)
13380       {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13381        &EmulateInstructionARM::EmulateADDImmThumb,
13382        "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13383       {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13384        &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13385       {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13386        &EmulateInstructionARM::EmulateADDImmThumb,
13387        "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13388       {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13389        &EmulateInstructionARM::EmulateADDImmThumb,
13390        "addw<c> <Rd>,<Rn>,#<imm12>"},
13391       // sub (immediate, Thumb)
13392       {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13393        &EmulateInstructionARM::EmulateSUBImmThumb,
13394        "subs|sub<c> <Rd>, <Rn> #imm3"},
13395       {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13396        &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13397       {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13398        &EmulateInstructionARM::EmulateSUBImmThumb,
13399        "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13400       {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13401        &EmulateInstructionARM::EmulateSUBImmThumb,
13402        "subw<c> <Rd>, <Rn>, #imm12"},
13403       // sub (sp minus immediate)
13404       {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13405        &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13406       {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13407        &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13408       // sub (register)
13409       {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13410        &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13411       {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13412        &EmulateInstructionARM::EmulateSUBReg,
13413        "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13414       // teq (immediate)
13415       {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13416        &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13417       // teq (register)
13418       {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13419        &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13420       // tst (immediate)
13421       {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13422        &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13423       // tst (register)
13424       {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13425        &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13426       {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13427        &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13428 
13429       // move from high register to high register
13430       {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13431        &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13432       // move from low register to low register
13433       {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13434        &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13435       // mov{s}<c>.w <Rd>, <Rm>
13436       {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13437        &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13438       // move immediate
13439       {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13440        &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13441       {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13442        &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13443       {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13444        &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13445       // mvn (immediate)
13446       {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13447        &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13448       // mvn (register)
13449       {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13450        &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13451       {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13452        &EmulateInstructionARM::EmulateMVNReg,
13453        "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13454       // cmn (immediate)
13455       {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13456        &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13457       // cmn (register)
13458       {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13459        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13460       {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13461        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13462       // cmp (immediate)
13463       {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13464        &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13465       {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13466        &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13467       // cmp (register) (Rn and Rm both from r0-r7)
13468       {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13469        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13470       // cmp (register) (Rn and Rm not both from r0-r7)
13471       {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13472        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13473       {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13474        &EmulateInstructionARM::EmulateCMPReg,
13475        "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13476       // asr (immediate)
13477       {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13478        &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13479       {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13480        &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13481       // asr (register)
13482       {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13483        &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13484       {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13485        &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13486       // lsl (immediate)
13487       {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13488        &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13489       {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13490        &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13491       // lsl (register)
13492       {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13493        &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13494       {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13495        &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13496       // lsr (immediate)
13497       {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13498        &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13499       {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13500        &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13501       // lsr (register)
13502       {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13503        &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13504       {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13505        &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13506       // rrx is a special case encoding of ror (immediate)
13507       {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13508        &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13509       // ror (immediate)
13510       {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13511        &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13512       // ror (register)
13513       {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13514        &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13515       {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13516        &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13517       // mul
13518       {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13519        &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13520       // mul
13521       {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13522        &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13523 
13524       // subs pc, lr and related instructions
13525       {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13526        &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13527 
13528       // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13529       // LDM.. Instructions in this table;
13530       // otherwise the wrong instructions will be selected.
13531 
13532       {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13533        &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13534       {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13535        &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13536 
13537       // Load instructions
13538       {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13539        &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13540       {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13541        &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13542       {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13543        &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13544       {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13545        &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13546       {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13547        &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13548       {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13549        &EmulateInstructionARM::EmulateLDRRtRnImm,
13550        "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13551       {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13552        &EmulateInstructionARM::EmulateLDRRtRnImm,
13553        "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13554       // Thumb2 PC-relative load into register
13555       {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13556        &EmulateInstructionARM::EmulateLDRRtPCRelative,
13557        "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13558       {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13559        &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13560       {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13561        &EmulateInstructionARM::EmulateLDRRegister,
13562        "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13563       {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13564        &EmulateInstructionARM::EmulateLDRBImmediate,
13565        "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13566       {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13567        &EmulateInstructionARM::EmulateLDRBImmediate,
13568        "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13569       {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13570        &EmulateInstructionARM::EmulateLDRBImmediate,
13571        "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13572       {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13573        &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13574       {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13575        &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13576       {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13577        &EmulateInstructionARM::EmulateLDRBRegister,
13578        "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13579       {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13580        &EmulateInstructionARM::EmulateLDRHImmediate,
13581        "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13582       {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13583        &EmulateInstructionARM::EmulateLDRHImmediate,
13584        "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13585       {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13586        &EmulateInstructionARM::EmulateLDRHImmediate,
13587        "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13588       {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13589        &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13590       {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13591        &EmulateInstructionARM::EmulateLDRHRegister,
13592        "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13593       {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13594        &EmulateInstructionARM::EmulateLDRHRegister,
13595        "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13596       {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13597        &EmulateInstructionARM::EmulateLDRSBImmediate,
13598        "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13599       {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13600        &EmulateInstructionARM::EmulateLDRSBImmediate,
13601        "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13602       {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13603        &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13604       {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13605        &EmulateInstructionARM::EmulateLDRSBRegister,
13606        "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13607       {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13608        &EmulateInstructionARM::EmulateLDRSBRegister,
13609        "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13610       {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13611        &EmulateInstructionARM::EmulateLDRSHImmediate,
13612        "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13613       {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13614        &EmulateInstructionARM::EmulateLDRSHImmediate,
13615        "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13616       {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13617        &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13618       {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13619        &EmulateInstructionARM::EmulateLDRSHRegister,
13620        "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13621       {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13622        &EmulateInstructionARM::EmulateLDRSHRegister,
13623        "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13624       {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13625        &EmulateInstructionARM::EmulateLDRDImmediate,
13626        "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13627       {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13628        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13629       {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13630        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13631       {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13632        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13633       {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13634        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13635       {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13636        &EmulateInstructionARM::EmulateVLD1Multiple,
13637        "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13638       {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13639        &EmulateInstructionARM::EmulateVLD1Single,
13640        "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13641       {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13642        &EmulateInstructionARM::EmulateVLD1SingleAll,
13643        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13644 
13645       // Store instructions
13646       {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13647        &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13648       {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13649        &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13650       {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13651        &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13652       {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13653        &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13654       {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13655        &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13656       {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13657        &EmulateInstructionARM::EmulateSTRThumb,
13658        "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13659       {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13660        &EmulateInstructionARM::EmulateSTRThumb,
13661        "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13662       {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13663        &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13664       {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13665        &EmulateInstructionARM::EmulateSTRRegister,
13666        "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13667       {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13668        &EmulateInstructionARM::EmulateSTRBThumb,
13669        "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13670       {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13671        &EmulateInstructionARM::EmulateSTRBThumb,
13672        "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13673       {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13674        &EmulateInstructionARM::EmulateSTRBThumb,
13675        "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13676       {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13677        &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13678       {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13679        &EmulateInstructionARM::EmulateSTRHRegister,
13680        "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13681       {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13682        &EmulateInstructionARM::EmulateSTREX,
13683        "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13684       {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13685        &EmulateInstructionARM::EmulateSTRDImm,
13686        "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13687       {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13688        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13689       {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13690        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13691       {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13692        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13693       {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13694        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13695       {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13696        &EmulateInstructionARM::EmulateVST1Multiple,
13697        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13698       {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13699        &EmulateInstructionARM::EmulateVST1Single,
13700        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13701 
13702       // Other instructions
13703       {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13704        &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13705       {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13706        &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13707       {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13708        &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13709       {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13710        &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13711       {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13712        &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13713       {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13714        &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13715       {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13716        &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13717       {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13718        &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13719   };
13720 
13721   const size_t k_num_thumb_opcodes = std::size(g_thumb_opcodes);
13722   for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13723     if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13724         (g_thumb_opcodes[i].variants & arm_isa) != 0)
13725       return &g_thumb_opcodes[i];
13726   }
13727   return nullptr;
13728 }
13729 
13730 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13731   m_arch = arch;
13732   m_arm_isa = 0;
13733   llvm::StringRef arch_cstr = arch.GetArchitectureName();
13734   if (arch_cstr.equals_insensitive("armv4t"))
13735     m_arm_isa = ARMv4T;
13736   else if (arch_cstr.equals_insensitive("armv5tej"))
13737     m_arm_isa = ARMv5TEJ;
13738   else if (arch_cstr.equals_insensitive("armv5te"))
13739     m_arm_isa = ARMv5TE;
13740   else if (arch_cstr.equals_insensitive("armv5t"))
13741     m_arm_isa = ARMv5T;
13742   else if (arch_cstr.equals_insensitive("armv6k"))
13743     m_arm_isa = ARMv6K;
13744   else if (arch_cstr.equals_insensitive("armv6t2"))
13745     m_arm_isa = ARMv6T2;
13746   else if (arch_cstr.equals_insensitive("armv7s"))
13747     m_arm_isa = ARMv7S;
13748   else if (arch_cstr.equals_insensitive("arm"))
13749     m_arm_isa = ARMvAll;
13750   else if (arch_cstr.equals_insensitive("thumb"))
13751     m_arm_isa = ARMvAll;
13752   else if (arch_cstr.starts_with_insensitive("armv4"))
13753     m_arm_isa = ARMv4;
13754   else if (arch_cstr.starts_with_insensitive("armv6"))
13755     m_arm_isa = ARMv6;
13756   else if (arch_cstr.starts_with_insensitive("armv7"))
13757     m_arm_isa = ARMv7;
13758   else if (arch_cstr.starts_with_insensitive("armv8"))
13759     m_arm_isa = ARMv8;
13760   return m_arm_isa != 0;
13761 }
13762 
13763 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13764                                            const Address &inst_addr,
13765                                            Target *target) {
13766   if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13767     if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13768         m_arch.IsAlwaysThumbInstructions())
13769       m_opcode_mode = eModeThumb;
13770     else {
13771       AddressClass addr_class = inst_addr.GetAddressClass();
13772 
13773       if ((addr_class == AddressClass::eCode) ||
13774           (addr_class == AddressClass::eUnknown))
13775         m_opcode_mode = eModeARM;
13776       else if (addr_class == AddressClass::eCodeAlternateISA)
13777         m_opcode_mode = eModeThumb;
13778       else
13779         return false;
13780     }
13781     if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13782       m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13783     else
13784       m_opcode_cpsr = CPSR_MODE_USR;
13785     return true;
13786   }
13787   return false;
13788 }
13789 
13790 bool EmulateInstructionARM::ReadInstruction() {
13791   bool success = false;
13792   m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13793                                        LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13794   if (success) {
13795     addr_t pc =
13796         ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13797                              LLDB_INVALID_ADDRESS, &success);
13798     if (success) {
13799       Context read_inst_context;
13800       read_inst_context.type = eContextReadOpcode;
13801       read_inst_context.SetNoArgs();
13802 
13803       if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13804         m_opcode_mode = eModeThumb;
13805         uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13806 
13807         if (success) {
13808           if ((thumb_opcode & 0xe000) != 0xe000 ||
13809               ((thumb_opcode & 0x1800u) == 0)) {
13810             m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13811           } else {
13812             m_opcode.SetOpcode32(
13813                 (thumb_opcode << 16) |
13814                     MemARead(read_inst_context, pc + 2, 2, 0, &success),
13815                 GetByteOrder());
13816           }
13817         }
13818       } else {
13819         m_opcode_mode = eModeARM;
13820         m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13821                              GetByteOrder());
13822       }
13823 
13824       if (!m_ignore_conditions) {
13825         // If we are not ignoreing the conditions then init the it session from
13826         // the current value of cpsr.
13827         uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13828                       Bits32(m_opcode_cpsr, 26, 25);
13829         if (it != 0)
13830           m_it_session.InitIT(it);
13831       }
13832     }
13833   }
13834   if (!success) {
13835     m_opcode_mode = eModeInvalid;
13836     m_addr = LLDB_INVALID_ADDRESS;
13837   }
13838   return success;
13839 }
13840 
13841 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13842 
13843 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13844   // If we are ignoring conditions, then always return true. this allows us to
13845   // iterate over disassembly code and still emulate an instruction even if we
13846   // don't have all the right bits set in the CPSR register...
13847   if (m_ignore_conditions)
13848     return true;
13849 
13850   const uint32_t cond = CurrentCond(opcode);
13851   if (cond == UINT32_MAX)
13852     return false;
13853 
13854   bool result = false;
13855   switch (UnsignedBits(cond, 3, 1)) {
13856   case 0:
13857     if (m_opcode_cpsr == 0)
13858       result = true;
13859     else
13860       result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13861     break;
13862   case 1:
13863     if (m_opcode_cpsr == 0)
13864       result = true;
13865     else
13866       result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13867     break;
13868   case 2:
13869     if (m_opcode_cpsr == 0)
13870       result = true;
13871     else
13872       result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13873     break;
13874   case 3:
13875     if (m_opcode_cpsr == 0)
13876       result = true;
13877     else
13878       result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13879     break;
13880   case 4:
13881     if (m_opcode_cpsr == 0)
13882       result = true;
13883     else
13884       result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13885                ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13886     break;
13887   case 5:
13888     if (m_opcode_cpsr == 0)
13889       result = true;
13890     else {
13891       bool n = (m_opcode_cpsr & MASK_CPSR_N);
13892       bool v = (m_opcode_cpsr & MASK_CPSR_V);
13893       result = n == v;
13894     }
13895     break;
13896   case 6:
13897     if (m_opcode_cpsr == 0)
13898       result = true;
13899     else {
13900       bool n = (m_opcode_cpsr & MASK_CPSR_N);
13901       bool v = (m_opcode_cpsr & MASK_CPSR_V);
13902       result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13903     }
13904     break;
13905   case 7:
13906     // Always execute (cond == 0b1110, or the special 0b1111 which gives
13907     // opcodes different meanings, but always means execution happens.
13908     return true;
13909   }
13910 
13911   if (cond & 1)
13912     result = !result;
13913   return result;
13914 }
13915 
13916 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13917   switch (m_opcode_mode) {
13918   case eModeInvalid:
13919     break;
13920 
13921   case eModeARM:
13922     return UnsignedBits(opcode, 31, 28);
13923 
13924   case eModeThumb:
13925     // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13926     // 'cond' field of the encoding.
13927     {
13928       const uint32_t byte_size = m_opcode.GetByteSize();
13929       if (byte_size == 2) {
13930         if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13931           return Bits32(opcode, 11, 8);
13932       } else if (byte_size == 4) {
13933         if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13934             Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13935           return Bits32(opcode, 25, 22);
13936         }
13937       } else
13938         // We have an invalid thumb instruction, let's bail out.
13939         break;
13940 
13941       return m_it_session.GetCond();
13942     }
13943   }
13944   return UINT32_MAX; // Return invalid value
13945 }
13946 
13947 bool EmulateInstructionARM::InITBlock() {
13948   return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13949 }
13950 
13951 bool EmulateInstructionARM::LastInITBlock() {
13952   return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13953 }
13954 
13955 bool EmulateInstructionARM::BadMode(uint32_t mode) {
13956 
13957   switch (mode) {
13958   case 16:
13959     return false; // '10000'
13960   case 17:
13961     return false; // '10001'
13962   case 18:
13963     return false; // '10010'
13964   case 19:
13965     return false; // '10011'
13966   case 22:
13967     return false; // '10110'
13968   case 23:
13969     return false; // '10111'
13970   case 27:
13971     return false; // '11011'
13972   case 31:
13973     return false; // '11111'
13974   default:
13975     return true;
13976   }
13977   return true;
13978 }
13979 
13980 bool EmulateInstructionARM::CurrentModeIsPrivileged() {
13981   uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
13982 
13983   if (BadMode(mode))
13984     return false;
13985 
13986   if (mode == 16)
13987     return false;
13988 
13989   return true;
13990 }
13991 
13992 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
13993                                              bool affect_execstate) {
13994   bool privileged = CurrentModeIsPrivileged();
13995 
13996   uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
13997 
13998   if (BitIsSet(bytemask, 3)) {
13999     tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14000     if (affect_execstate)
14001       tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14002   }
14003 
14004   if (BitIsSet(bytemask, 2)) {
14005     tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14006   }
14007 
14008   if (BitIsSet(bytemask, 1)) {
14009     if (affect_execstate)
14010       tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14011     tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14012     if (privileged)
14013       tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14014   }
14015 
14016   if (BitIsSet(bytemask, 0)) {
14017     if (privileged)
14018       tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14019     if (affect_execstate)
14020       tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14021     if (privileged)
14022       tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14023   }
14024 
14025   m_opcode_cpsr = tmp_cpsr;
14026 }
14027 
14028 bool EmulateInstructionARM::BranchWritePC(const Context &context,
14029                                           uint32_t addr) {
14030   addr_t target;
14031 
14032   // Check the current instruction set.
14033   if (CurrentInstrSet() == eModeARM)
14034     target = addr & 0xfffffffc;
14035   else
14036     target = addr & 0xfffffffe;
14037 
14038   return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14039                                LLDB_REGNUM_GENERIC_PC, target);
14040 }
14041 
14042 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14043 // inspecting addr.
14044 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14045   addr_t target;
14046   // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14047   // we want to record it and issue a WriteRegister callback so the clients can
14048   // track the mode changes accordingly.
14049   bool cpsr_changed = false;
14050 
14051   if (BitIsSet(addr, 0)) {
14052     if (CurrentInstrSet() != eModeThumb) {
14053       SelectInstrSet(eModeThumb);
14054       cpsr_changed = true;
14055     }
14056     target = addr & 0xfffffffe;
14057     context.SetISA(eModeThumb);
14058   } else if (BitIsClear(addr, 1)) {
14059     if (CurrentInstrSet() != eModeARM) {
14060       SelectInstrSet(eModeARM);
14061       cpsr_changed = true;
14062     }
14063     target = addr & 0xfffffffc;
14064     context.SetISA(eModeARM);
14065   } else
14066     return false; // address<1:0> == '10' => UNPREDICTABLE
14067 
14068   if (cpsr_changed) {
14069     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14070                                LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14071       return false;
14072   }
14073   return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14074                                LLDB_REGNUM_GENERIC_PC, target);
14075 }
14076 
14077 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14078 // versions.
14079 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14080   if (ArchVersion() >= ARMv5T)
14081     return BXWritePC(context, addr);
14082   else
14083     return BranchWritePC((const Context)context, addr);
14084 }
14085 
14086 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14087 // versions and current instruction set.
14088 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14089   if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14090     return BXWritePC(context, addr);
14091   else
14092     return BranchWritePC((const Context)context, addr);
14093 }
14094 
14095 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14096   return m_opcode_mode;
14097 }
14098 
14099 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14100 // ReadInstruction() is performed.  This function has a side effect of updating
14101 // the m_new_inst_cpsr member variable if necessary.
14102 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14103   m_new_inst_cpsr = m_opcode_cpsr;
14104   switch (arm_or_thumb) {
14105   default:
14106     return false;
14107   case eModeARM:
14108     // Clear the T bit.
14109     m_new_inst_cpsr &= ~MASK_CPSR_T;
14110     break;
14111   case eModeThumb:
14112     // Set the T bit.
14113     m_new_inst_cpsr |= MASK_CPSR_T;
14114     break;
14115   }
14116   return true;
14117 }
14118 
14119 // This function returns TRUE if the processor currently provides support for
14120 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14121 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
14122 bool EmulateInstructionARM::UnalignedSupport() {
14123   return (ArchVersion() >= ARMv7);
14124 }
14125 
14126 // The main addition and subtraction instructions can produce status
14127 // information about both unsigned carry and signed overflow conditions.  This
14128 // status information can be used to synthesize multi-word additions and
14129 // subtractions.
14130 EmulateInstructionARM::AddWithCarryResult
14131 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14132   uint32_t result;
14133   uint8_t carry_out;
14134   uint8_t overflow;
14135 
14136   uint64_t unsigned_sum = x + y + carry_in;
14137   int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14138 
14139   result = UnsignedBits(unsigned_sum, 31, 0);
14140   //    carry_out = (result == unsigned_sum ? 0 : 1);
14141   overflow = ((int32_t)result == signed_sum ? 0 : 1);
14142 
14143   if (carry_in)
14144     carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14145   else
14146     carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14147 
14148   AddWithCarryResult res = {result, carry_out, overflow};
14149   return res;
14150 }
14151 
14152 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14153   lldb::RegisterKind reg_kind;
14154   uint32_t reg_num;
14155   switch (num) {
14156   case SP_REG:
14157     reg_kind = eRegisterKindGeneric;
14158     reg_num = LLDB_REGNUM_GENERIC_SP;
14159     break;
14160   case LR_REG:
14161     reg_kind = eRegisterKindGeneric;
14162     reg_num = LLDB_REGNUM_GENERIC_RA;
14163     break;
14164   case PC_REG:
14165     reg_kind = eRegisterKindGeneric;
14166     reg_num = LLDB_REGNUM_GENERIC_PC;
14167     break;
14168   default:
14169     if (num < SP_REG) {
14170       reg_kind = eRegisterKindDWARF;
14171       reg_num = dwarf_r0 + num;
14172     } else {
14173       // assert(0 && "Invalid register number");
14174       *success = false;
14175       return UINT32_MAX;
14176     }
14177     break;
14178   }
14179 
14180   // Read our register.
14181   uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14182 
14183   // When executing an ARM instruction , PC reads as the address of the current
14184   // instruction plus 8. When executing a Thumb instruction , PC reads as the
14185   // address of the current instruction plus 4.
14186   if (num == 15) {
14187     if (CurrentInstrSet() == eModeARM)
14188       val += 8;
14189     else
14190       val += 4;
14191   }
14192 
14193   return val;
14194 }
14195 
14196 // Write the result to the ARM core register Rd, and optionally update the
14197 // condition flags based on the result.
14198 //
14199 // This helper method tries to encapsulate the following pseudocode from the
14200 // ARM Architecture Reference Manual:
14201 //
14202 // if d == 15 then         // Can only occur for encoding A1
14203 //     ALUWritePC(result); // setflags is always FALSE here
14204 // else
14205 //     R[d] = result;
14206 //     if setflags then
14207 //         APSR.N = result<31>;
14208 //         APSR.Z = IsZeroBit(result);
14209 //         APSR.C = carry;
14210 //         // APSR.V unchanged
14211 //
14212 // In the above case, the API client does not pass in the overflow arg, which
14213 // defaults to ~0u.
14214 bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14215     Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14216     const uint32_t carry, const uint32_t overflow) {
14217   if (Rd == 15) {
14218     if (!ALUWritePC(context, result))
14219       return false;
14220   } else {
14221     lldb::RegisterKind reg_kind;
14222     uint32_t reg_num;
14223     switch (Rd) {
14224     case SP_REG:
14225       reg_kind = eRegisterKindGeneric;
14226       reg_num = LLDB_REGNUM_GENERIC_SP;
14227       break;
14228     case LR_REG:
14229       reg_kind = eRegisterKindGeneric;
14230       reg_num = LLDB_REGNUM_GENERIC_RA;
14231       break;
14232     default:
14233       reg_kind = eRegisterKindDWARF;
14234       reg_num = dwarf_r0 + Rd;
14235     }
14236     if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14237       return false;
14238     if (setflags)
14239       return WriteFlags(context, result, carry, overflow);
14240   }
14241   return true;
14242 }
14243 
14244 // This helper method tries to encapsulate the following pseudocode from the
14245 // ARM Architecture Reference Manual:
14246 //
14247 // APSR.N = result<31>;
14248 // APSR.Z = IsZeroBit(result);
14249 // APSR.C = carry;
14250 // APSR.V = overflow
14251 //
14252 // Default arguments can be specified for carry and overflow parameters, which
14253 // means not to update the respective flags.
14254 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14255                                        const uint32_t carry,
14256                                        const uint32_t overflow) {
14257   m_new_inst_cpsr = m_opcode_cpsr;
14258   SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14259   SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14260   if (carry != ~0u)
14261     SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14262   if (overflow != ~0u)
14263     SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14264   if (m_new_inst_cpsr != m_opcode_cpsr) {
14265     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14266                                LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14267       return false;
14268   }
14269   return true;
14270 }
14271 
14272 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14273   ARMOpcode *opcode_data = nullptr;
14274 
14275   if (m_opcode_mode == eModeThumb)
14276     opcode_data =
14277         GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14278   else if (m_opcode_mode == eModeARM)
14279     opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14280 
14281   const bool auto_advance_pc =
14282       evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14283   m_ignore_conditions =
14284       evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14285 
14286   bool success = false;
14287   if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14288     m_opcode_cpsr =
14289         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14290   }
14291 
14292   // Only return false if we are unable to read the CPSR if we care about
14293   // conditions
14294   if (!success && !m_ignore_conditions)
14295     return false;
14296 
14297   uint32_t orig_pc_value = 0;
14298   if (auto_advance_pc) {
14299     orig_pc_value =
14300         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14301     if (!success)
14302       return false;
14303   }
14304 
14305   // Call the Emulate... function if we managed to decode the opcode.
14306   if (opcode_data) {
14307     success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14308                                              opcode_data->encoding);
14309     if (!success)
14310       return false;
14311   }
14312 
14313   // Advance the ITSTATE bits to their values for the next instruction if we
14314   // haven't just executed an IT instruction what initialized it.
14315   if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14316       (opcode_data == nullptr ||
14317        opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14318     m_it_session.ITAdvance();
14319 
14320   if (auto_advance_pc) {
14321     uint32_t after_pc_value =
14322         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14323     if (!success)
14324       return false;
14325 
14326     if (after_pc_value == orig_pc_value) {
14327       after_pc_value += m_opcode.GetByteSize();
14328 
14329       EmulateInstruction::Context context;
14330       context.type = eContextAdvancePC;
14331       context.SetNoArgs();
14332       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14333                                  after_pc_value))
14334         return false;
14335     }
14336   }
14337   return true;
14338 }
14339 
14340 EmulateInstruction::InstructionCondition
14341 EmulateInstructionARM::GetInstructionCondition() {
14342   const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14343   if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14344     return EmulateInstruction::UnconditionalCondition;
14345   return cond;
14346 }
14347 
14348 bool EmulateInstructionARM::TestEmulation(Stream &out_stream, ArchSpec &arch,
14349                                           OptionValueDictionary *test_data) {
14350   if (!test_data) {
14351     out_stream.Printf("TestEmulation: Missing test data.\n");
14352     return false;
14353   }
14354 
14355   static constexpr llvm::StringLiteral opcode_key("opcode");
14356   static constexpr llvm::StringLiteral before_key("before_state");
14357   static constexpr llvm::StringLiteral after_key("after_state");
14358 
14359   OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14360 
14361   uint32_t test_opcode;
14362   if ((value_sp.get() == nullptr) ||
14363       (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14364     out_stream.Printf("TestEmulation: Error reading opcode from test file.\n");
14365     return false;
14366   }
14367   test_opcode = value_sp->GetValueAs<uint64_t>().value_or(0);
14368 
14369   if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14370       arch.IsAlwaysThumbInstructions()) {
14371     m_opcode_mode = eModeThumb;
14372     if (test_opcode < 0x10000)
14373       m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14374     else
14375       m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14376   } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14377     m_opcode_mode = eModeARM;
14378     m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14379   } else {
14380     out_stream.Printf("TestEmulation:  Invalid arch.\n");
14381     return false;
14382   }
14383 
14384   EmulationStateARM before_state;
14385   EmulationStateARM after_state;
14386 
14387   value_sp = test_data->GetValueForKey(before_key);
14388   if ((value_sp.get() == nullptr) ||
14389       (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14390     out_stream.Printf("TestEmulation:  Failed to find 'before' state.\n");
14391     return false;
14392   }
14393 
14394   OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14395   if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14396     out_stream.Printf("TestEmulation:  Failed loading 'before' state.\n");
14397     return false;
14398   }
14399 
14400   value_sp = test_data->GetValueForKey(after_key);
14401   if ((value_sp.get() == nullptr) ||
14402       (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14403     out_stream.Printf("TestEmulation:  Failed to find 'after' state.\n");
14404     return false;
14405   }
14406 
14407   state_dictionary = value_sp->GetAsDictionary();
14408   if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14409     out_stream.Printf("TestEmulation: Failed loading 'after' state.\n");
14410     return false;
14411   }
14412 
14413   SetBaton((void *)&before_state);
14414   SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14415                &EmulationStateARM::WritePseudoMemory,
14416                &EmulationStateARM::ReadPseudoRegister,
14417                &EmulationStateARM::WritePseudoRegister);
14418 
14419   bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14420   if (!success) {
14421     out_stream.Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14422     return false;
14423   }
14424 
14425   success = before_state.CompareState(after_state, out_stream);
14426   if (!success)
14427     out_stream.Printf("TestEmulation:  State after emulation does not match "
14428                       "'after' state.\n");
14429 
14430   return success;
14431 }
14432 //
14433 //
14434 // const char *
14435 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14436 //{
14437 //    if (reg_kind == eRegisterKindGeneric)
14438 //    {
14439 //        switch (reg_num)
14440 //        {
14441 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14442 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14443 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14444 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14445 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14446 //        default: return NULL;
14447 //        }
14448 //    }
14449 //    else if (reg_kind == eRegisterKindDWARF)
14450 //    {
14451 //        return GetARMDWARFRegisterName (reg_num);
14452 //    }
14453 //    return NULL;
14454 //}
14455 //
14456 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14457   unwind_plan.Clear();
14458   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14459 
14460   UnwindPlan::RowSP row(new UnwindPlan::Row);
14461 
14462   // Our previous Call Frame Address is the stack pointer
14463   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14464 
14465   unwind_plan.AppendRow(row);
14466   unwind_plan.SetSourceName("EmulateInstructionARM");
14467   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14468   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14469   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
14470   unwind_plan.SetReturnAddressRegister(dwarf_lr);
14471   return true;
14472 }
14473