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 
LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM,InstructionARM)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.
CountITSize(uint32_t ITMask)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.
InitIT(uint32_t bits7_0)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.
ITAdvance()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.
InITBlock()646 bool ITSession::InITBlock() { return ITCounter != 0; }
647 
648 // Return true if we're the last instruction inside an IT Block.
LastInITBlock()649 bool ITSession::LastInITBlock() { return ITCounter == 1; }
650 
651 // Get condition bits for the current thumb instruction.
GetCond()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 
Initialize()708 void EmulateInstructionARM::Initialize() {
709   PluginManager::RegisterPlugin(GetPluginNameStatic(),
710                                 GetPluginDescriptionStatic(), CreateInstance);
711 }
712 
Terminate()713 void EmulateInstructionARM::Terminate() {
714   PluginManager::UnregisterPlugin(CreateInstance);
715 }
716 
GetPluginDescriptionStatic()717 llvm::StringRef EmulateInstructionARM::GetPluginDescriptionStatic() {
718   return "Emulate instructions for the ARM architecture.";
719 }
720 
721 EmulateInstruction *
CreateInstance(const ArchSpec & arch,InstructionType inst_type)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 
SetTargetTriple(const ArchSpec & arch)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.
WriteBits32UnknownToMemory(addr_t address)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.
WriteBits32Unknown(int n)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>
GetRegisterInfo(lldb::RegisterKind reg_kind,uint32_t reg_num)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 
GetFramePointerRegisterNumber() const821 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   case llvm::Triple::XROS:
834   // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
835     is_apple = true;
836     break;
837   default:
838     break;
839   }
840 
841   /* On Apple iOS et al, the frame pointer register is always r7.
842    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
843    * Windows on ARM, which is in thumb mode, uses r11 though.
844    */
845 
846   uint32_t fp_regnum = 11;
847 
848   if (is_apple)
849     fp_regnum = 7;
850 
851   if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
852     fp_regnum = 7;
853 
854   return fp_regnum;
855 }
856 
GetFramePointerDWARFRegisterNumber() const857 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
858   bool is_apple = false;
859   if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
860     is_apple = true;
861   switch (m_arch.GetTriple().getOS()) {
862   case llvm::Triple::Darwin:
863   case llvm::Triple::MacOSX:
864   case llvm::Triple::IOS:
865     is_apple = true;
866     break;
867   default:
868     break;
869   }
870 
871   /* On Apple iOS et al, the frame pointer register is always r7.
872    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
873    * Windows on ARM, which is in thumb mode, uses r11 though.
874    */
875 
876   uint32_t fp_regnum = dwarf_r11;
877 
878   if (is_apple)
879     fp_regnum = dwarf_r7;
880 
881   if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
882     fp_regnum = dwarf_r7;
883 
884   return fp_regnum;
885 }
886 
887 // Push Multiple Registers stores multiple registers to the stack, storing to
888 // consecutive memory locations ending just below the address in SP, and
889 // updates
890 // SP to point to the start of the stored data.
EmulatePUSH(const uint32_t opcode,const ARMEncoding encoding)891 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
892                                         const ARMEncoding encoding) {
893 #if 0
894     // ARM pseudo code...
895     if (ConditionPassed())
896     {
897         EncodingSpecificOperations();
898         NullCheckIfThumbEE(13);
899         address = SP - 4*BitCount(registers);
900 
901         for (i = 0 to 14)
902         {
903             if (registers<i> == '1')
904             {
905                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
906                     MemA[address,4] = bits(32) UNKNOWN;
907                 else
908                     MemA[address,4] = R[i];
909                 address = address + 4;
910             }
911         }
912 
913         if (registers<15> == '1') // Only possible for encoding A1 or A2
914             MemA[address,4] = PCStoreValue();
915 
916         SP = SP - 4*BitCount(registers);
917     }
918 #endif
919 
920   bool success = false;
921   if (ConditionPassed(opcode)) {
922     const uint32_t addr_byte_size = GetAddressByteSize();
923     const addr_t sp = ReadCoreReg(SP_REG, &success);
924     if (!success)
925       return false;
926     uint32_t registers = 0;
927     uint32_t Rt; // the source register
928     switch (encoding) {
929     case eEncodingT1:
930       registers = Bits32(opcode, 7, 0);
931       // The M bit represents LR.
932       if (Bit32(opcode, 8))
933         registers |= (1u << 14);
934       // if BitCount(registers) < 1 then UNPREDICTABLE;
935       if (BitCount(registers) < 1)
936         return false;
937       break;
938     case eEncodingT2:
939       // Ignore bits 15 & 13.
940       registers = Bits32(opcode, 15, 0) & ~0xa000;
941       // if BitCount(registers) < 2 then UNPREDICTABLE;
942       if (BitCount(registers) < 2)
943         return false;
944       break;
945     case eEncodingT3:
946       Rt = Bits32(opcode, 15, 12);
947       // if BadReg(t) then UNPREDICTABLE;
948       if (BadReg(Rt))
949         return false;
950       registers = (1u << Rt);
951       break;
952     case eEncodingA1:
953       registers = Bits32(opcode, 15, 0);
954       // Instead of return false, let's handle the following case as well,
955       // which amounts to pushing one reg onto the full descending stacks.
956       // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
957       break;
958     case eEncodingA2:
959       Rt = Bits32(opcode, 15, 12);
960       // if t == 13 then UNPREDICTABLE;
961       if (Rt == dwarf_sp)
962         return false;
963       registers = (1u << Rt);
964       break;
965     default:
966       return false;
967     }
968     addr_t sp_offset = addr_byte_size * BitCount(registers);
969     addr_t addr = sp - sp_offset;
970     uint32_t i;
971 
972     EmulateInstruction::Context context;
973     context.type = EmulateInstruction::eContextPushRegisterOnStack;
974     std::optional<RegisterInfo> sp_reg =
975         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
976     for (i = 0; i < 15; ++i) {
977       if (BitIsSet(registers, i)) {
978         std::optional<RegisterInfo> reg_info =
979             GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
980         context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
981         uint32_t reg_value = ReadCoreReg(i, &success);
982         if (!success)
983           return false;
984         if (!MemAWrite(context, addr, reg_value, addr_byte_size))
985           return false;
986         addr += addr_byte_size;
987       }
988     }
989 
990     if (BitIsSet(registers, 15)) {
991       std::optional<RegisterInfo> reg_info =
992           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
993       context.SetRegisterToRegisterPlusOffset(*reg_info, *sp_reg, addr - sp);
994       const uint32_t pc = ReadCoreReg(PC_REG, &success);
995       if (!success)
996         return false;
997       if (!MemAWrite(context, addr, pc, addr_byte_size))
998         return false;
999     }
1000 
1001     context.type = EmulateInstruction::eContextAdjustStackPointer;
1002     context.SetImmediateSigned(-sp_offset);
1003 
1004     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1005                                LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1006       return false;
1007   }
1008   return true;
1009 }
1010 
1011 // Pop Multiple Registers loads multiple registers from the stack, loading from
1012 // consecutive memory locations staring at the address in SP, and updates
1013 // SP to point just above the loaded data.
EmulatePOP(const uint32_t opcode,const ARMEncoding encoding)1014 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1015                                        const ARMEncoding encoding) {
1016 #if 0
1017     // ARM pseudo code...
1018     if (ConditionPassed())
1019     {
1020         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1021         address = SP;
1022         for i = 0 to 14
1023             if registers<i> == '1' then
1024                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1025         if registers<15> == '1' then
1026             if UnalignedAllowed then
1027                 LoadWritePC(MemU[address,4]);
1028             else
1029                 LoadWritePC(MemA[address,4]);
1030         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1031         if registers<13> == '1' then SP = bits(32) UNKNOWN;
1032     }
1033 #endif
1034 
1035   bool success = false;
1036 
1037   if (ConditionPassed(opcode)) {
1038     const uint32_t addr_byte_size = GetAddressByteSize();
1039     const addr_t sp = ReadCoreReg(SP_REG, &success);
1040     if (!success)
1041       return false;
1042     uint32_t registers = 0;
1043     uint32_t Rt; // the destination register
1044     switch (encoding) {
1045     case eEncodingT1:
1046       registers = Bits32(opcode, 7, 0);
1047       // The P bit represents PC.
1048       if (Bit32(opcode, 8))
1049         registers |= (1u << 15);
1050       // if BitCount(registers) < 1 then UNPREDICTABLE;
1051       if (BitCount(registers) < 1)
1052         return false;
1053       break;
1054     case eEncodingT2:
1055       // Ignore bit 13.
1056       registers = Bits32(opcode, 15, 0) & ~0x2000;
1057       // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1058       // UNPREDICTABLE;
1059       if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1060         return false;
1061       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1062       // UNPREDICTABLE;
1063       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1064         return false;
1065       break;
1066     case eEncodingT3:
1067       Rt = Bits32(opcode, 15, 12);
1068       // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1069       // UNPREDICTABLE;
1070       if (Rt == 13)
1071         return false;
1072       if (Rt == 15 && InITBlock() && !LastInITBlock())
1073         return false;
1074       registers = (1u << Rt);
1075       break;
1076     case eEncodingA1:
1077       registers = Bits32(opcode, 15, 0);
1078       // Instead of return false, let's handle the following case as well,
1079       // which amounts to popping one reg from the full descending stacks.
1080       // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1081 
1082       // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1083       if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1084         return false;
1085       break;
1086     case eEncodingA2:
1087       Rt = Bits32(opcode, 15, 12);
1088       // if t == 13 then UNPREDICTABLE;
1089       if (Rt == dwarf_sp)
1090         return false;
1091       registers = (1u << Rt);
1092       break;
1093     default:
1094       return false;
1095     }
1096     addr_t sp_offset = addr_byte_size * BitCount(registers);
1097     addr_t addr = sp;
1098     uint32_t i, data;
1099 
1100     EmulateInstruction::Context context;
1101     context.type = EmulateInstruction::eContextPopRegisterOffStack;
1102 
1103     std::optional<RegisterInfo> sp_reg =
1104         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1105 
1106     for (i = 0; i < 15; ++i) {
1107       if (BitIsSet(registers, i)) {
1108         context.SetAddress(addr);
1109         data = MemARead(context, addr, 4, 0, &success);
1110         if (!success)
1111           return false;
1112         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1113                                    data))
1114           return false;
1115         addr += addr_byte_size;
1116       }
1117     }
1118 
1119     if (BitIsSet(registers, 15)) {
1120       context.SetRegisterPlusOffset(*sp_reg, addr - sp);
1121       data = MemARead(context, addr, 4, 0, &success);
1122       if (!success)
1123         return false;
1124       // In ARMv5T and above, this is an interworking branch.
1125       if (!LoadWritePC(context, data))
1126         return false;
1127       // addr += addr_byte_size;
1128     }
1129 
1130     context.type = EmulateInstruction::eContextAdjustStackPointer;
1131     context.SetImmediateSigned(sp_offset);
1132 
1133     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1134                                LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1135       return false;
1136   }
1137   return true;
1138 }
1139 
1140 // Set r7 or ip to point to saved value residing within the stack.
1141 // ADD (SP plus immediate)
EmulateADDRdSPImm(const uint32_t opcode,const ARMEncoding encoding)1142 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1143                                               const ARMEncoding encoding) {
1144 #if 0
1145     // ARM pseudo code...
1146     if (ConditionPassed())
1147     {
1148         EncodingSpecificOperations();
1149         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1150         if d == 15 then
1151            ALUWritePC(result); // setflags is always FALSE here
1152         else
1153             R[d] = result;
1154             if setflags then
1155                 APSR.N = result<31>;
1156                 APSR.Z = IsZeroBit(result);
1157                 APSR.C = carry;
1158                 APSR.V = overflow;
1159     }
1160 #endif
1161 
1162   bool success = false;
1163 
1164   if (ConditionPassed(opcode)) {
1165     const addr_t sp = ReadCoreReg(SP_REG, &success);
1166     if (!success)
1167       return false;
1168     uint32_t Rd; // the destination register
1169     uint32_t imm32;
1170     switch (encoding) {
1171     case eEncodingT1:
1172       Rd = 7;
1173       imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1174       break;
1175     case eEncodingA1:
1176       Rd = Bits32(opcode, 15, 12);
1177       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1178       break;
1179     default:
1180       return false;
1181     }
1182     addr_t sp_offset = imm32;
1183     addr_t addr = sp + sp_offset; // a pointer to the stack area
1184 
1185     EmulateInstruction::Context context;
1186     if (Rd == GetFramePointerRegisterNumber())
1187       context.type = eContextSetFramePointer;
1188     else
1189       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1190     std::optional<RegisterInfo> sp_reg =
1191         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1192     context.SetRegisterPlusOffset(*sp_reg, sp_offset);
1193 
1194     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1195                                addr))
1196       return false;
1197   }
1198   return true;
1199 }
1200 
1201 // Set r7 or ip to the current stack pointer.
1202 // MOV (register)
EmulateMOVRdSP(const uint32_t opcode,const ARMEncoding encoding)1203 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1204                                            const ARMEncoding encoding) {
1205 #if 0
1206     // ARM pseudo code...
1207     if (ConditionPassed())
1208     {
1209         EncodingSpecificOperations();
1210         result = R[m];
1211         if d == 15 then
1212             ALUWritePC(result); // setflags is always FALSE here
1213         else
1214             R[d] = result;
1215             if setflags then
1216                 APSR.N = result<31>;
1217                 APSR.Z = IsZeroBit(result);
1218                 // APSR.C unchanged
1219                 // APSR.V unchanged
1220     }
1221 #endif
1222 
1223   bool success = false;
1224 
1225   if (ConditionPassed(opcode)) {
1226     const addr_t sp = ReadCoreReg(SP_REG, &success);
1227     if (!success)
1228       return false;
1229     uint32_t Rd; // the destination register
1230     switch (encoding) {
1231     case eEncodingT1:
1232       Rd = 7;
1233       break;
1234     case eEncodingA1:
1235       Rd = 12;
1236       break;
1237     default:
1238       return false;
1239     }
1240 
1241     EmulateInstruction::Context context;
1242     if (Rd == GetFramePointerRegisterNumber())
1243       context.type = EmulateInstruction::eContextSetFramePointer;
1244     else
1245       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1246     std::optional<RegisterInfo> sp_reg =
1247         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1248     context.SetRegisterPlusOffset(*sp_reg, 0);
1249 
1250     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1251       return false;
1252   }
1253   return true;
1254 }
1255 
1256 // Move from high register (r8-r15) to low register (r0-r7).
1257 // MOV (register)
EmulateMOVLowHigh(const uint32_t opcode,const ARMEncoding encoding)1258 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1259                                               const ARMEncoding encoding) {
1260   return EmulateMOVRdRm(opcode, encoding);
1261 }
1262 
1263 // Move from register to register.
1264 // MOV (register)
EmulateMOVRdRm(const uint32_t opcode,const ARMEncoding encoding)1265 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1266                                            const ARMEncoding encoding) {
1267 #if 0
1268     // ARM pseudo code...
1269     if (ConditionPassed())
1270     {
1271         EncodingSpecificOperations();
1272         result = R[m];
1273         if d == 15 then
1274             ALUWritePC(result); // setflags is always FALSE here
1275         else
1276             R[d] = result;
1277             if setflags then
1278                 APSR.N = result<31>;
1279                 APSR.Z = IsZeroBit(result);
1280                 // APSR.C unchanged
1281                 // APSR.V unchanged
1282     }
1283 #endif
1284 
1285   bool success = false;
1286 
1287   if (ConditionPassed(opcode)) {
1288     uint32_t Rm; // the source register
1289     uint32_t Rd; // the destination register
1290     bool setflags;
1291     switch (encoding) {
1292     case eEncodingT1:
1293       Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1294       Rm = Bits32(opcode, 6, 3);
1295       setflags = false;
1296       if (Rd == 15 && InITBlock() && !LastInITBlock())
1297         return false;
1298       break;
1299     case eEncodingT2:
1300       Rd = Bits32(opcode, 2, 0);
1301       Rm = Bits32(opcode, 5, 3);
1302       setflags = true;
1303       if (InITBlock())
1304         return false;
1305       break;
1306     case eEncodingT3:
1307       Rd = Bits32(opcode, 11, 8);
1308       Rm = Bits32(opcode, 3, 0);
1309       setflags = BitIsSet(opcode, 20);
1310       // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1311       if (setflags && (BadReg(Rd) || BadReg(Rm)))
1312         return false;
1313       // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1314       // UNPREDICTABLE;
1315       if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1316         return false;
1317       break;
1318     case eEncodingA1:
1319       Rd = Bits32(opcode, 15, 12);
1320       Rm = Bits32(opcode, 3, 0);
1321       setflags = BitIsSet(opcode, 20);
1322 
1323       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1324       // instructions;
1325       if (Rd == 15 && setflags)
1326         return EmulateSUBSPcLrEtc(opcode, encoding);
1327       break;
1328     default:
1329       return false;
1330     }
1331     uint32_t result = ReadCoreReg(Rm, &success);
1332     if (!success)
1333       return false;
1334 
1335     // The context specifies that Rm is to be moved into Rd.
1336     EmulateInstruction::Context context;
1337     if (Rd == 13)
1338       context.type = EmulateInstruction::eContextAdjustStackPointer;
1339     else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1340       context.type = EmulateInstruction::eContextSetFramePointer;
1341     else
1342       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1343     std::optional<RegisterInfo> dwarf_reg =
1344         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
1345     context.SetRegisterPlusOffset(*dwarf_reg, 0);
1346 
1347     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1348       return false;
1349   }
1350   return true;
1351 }
1352 
1353 // Move (immediate) writes an immediate value to the destination register.  It
1354 // can optionally update the condition flags based on the value.
1355 // MOV (immediate)
EmulateMOVRdImm(const uint32_t opcode,const ARMEncoding encoding)1356 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1357                                             const ARMEncoding encoding) {
1358 #if 0
1359     // ARM pseudo code...
1360     if (ConditionPassed())
1361     {
1362         EncodingSpecificOperations();
1363         result = imm32;
1364         if d == 15 then         // Can only occur for ARM encoding
1365             ALUWritePC(result); // setflags is always FALSE here
1366         else
1367             R[d] = result;
1368             if setflags then
1369                 APSR.N = result<31>;
1370                 APSR.Z = IsZeroBit(result);
1371                 APSR.C = carry;
1372                 // APSR.V unchanged
1373     }
1374 #endif
1375 
1376   if (ConditionPassed(opcode)) {
1377     uint32_t Rd;    // the destination register
1378     uint32_t imm32; // the immediate value to be written to Rd
1379     uint32_t carry =
1380         0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1381            // for setflags == false, this value is a don't care initialized to
1382            // 0 to silence the static analyzer
1383     bool setflags;
1384     switch (encoding) {
1385     case eEncodingT1:
1386       Rd = Bits32(opcode, 10, 8);
1387       setflags = !InITBlock();
1388       imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1389       carry = APSR_C;
1390 
1391       break;
1392 
1393     case eEncodingT2:
1394       Rd = Bits32(opcode, 11, 8);
1395       setflags = BitIsSet(opcode, 20);
1396       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1397       if (BadReg(Rd))
1398         return false;
1399 
1400       break;
1401 
1402     case eEncodingT3: {
1403       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1404       // 32);
1405       Rd = Bits32(opcode, 11, 8);
1406       setflags = false;
1407       uint32_t imm4 = Bits32(opcode, 19, 16);
1408       uint32_t imm3 = Bits32(opcode, 14, 12);
1409       uint32_t i = Bit32(opcode, 26);
1410       uint32_t imm8 = Bits32(opcode, 7, 0);
1411       imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1412 
1413       // if BadReg(d) then UNPREDICTABLE;
1414       if (BadReg(Rd))
1415         return false;
1416     } break;
1417 
1418     case eEncodingA1:
1419       // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1420       // ARMExpandImm_C(imm12, APSR.C);
1421       Rd = Bits32(opcode, 15, 12);
1422       setflags = BitIsSet(opcode, 20);
1423       imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1424 
1425       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1426       // instructions;
1427       if ((Rd == 15) && setflags)
1428         return EmulateSUBSPcLrEtc(opcode, encoding);
1429 
1430       break;
1431 
1432     case eEncodingA2: {
1433       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1434       Rd = Bits32(opcode, 15, 12);
1435       setflags = false;
1436       uint32_t imm4 = Bits32(opcode, 19, 16);
1437       uint32_t imm12 = Bits32(opcode, 11, 0);
1438       imm32 = (imm4 << 12) | imm12;
1439 
1440       // if d == 15 then UNPREDICTABLE;
1441       if (Rd == 15)
1442         return false;
1443     } break;
1444 
1445     default:
1446       return false;
1447     }
1448     uint32_t result = imm32;
1449 
1450     // The context specifies that an immediate is to be moved into Rd.
1451     EmulateInstruction::Context context;
1452     context.type = EmulateInstruction::eContextImmediate;
1453     context.SetNoArgs();
1454 
1455     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1456       return false;
1457   }
1458   return true;
1459 }
1460 
1461 // MUL multiplies two register values.  The least significant 32 bits of the
1462 // result are written to the destination
1463 // register.  These 32 bits do not depend on whether the source register values
1464 // are considered to be signed values or unsigned values.
1465 //
1466 // Optionally, it can update the condition flags based on the result.  In the
1467 // Thumb instruction set, this option is limited to only a few forms of the
1468 // instruction.
EmulateMUL(const uint32_t opcode,const ARMEncoding encoding)1469 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1470                                        const ARMEncoding encoding) {
1471 #if 0
1472     if ConditionPassed() then
1473         EncodingSpecificOperations();
1474         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1475         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1476         result = operand1 * operand2;
1477         R[d] = result<31:0>;
1478         if setflags then
1479             APSR.N = result<31>;
1480             APSR.Z = IsZeroBit(result);
1481             if ArchVersion() == 4 then
1482                 APSR.C = bit UNKNOWN;
1483             // else APSR.C unchanged
1484             // APSR.V always unchanged
1485 #endif
1486 
1487   if (ConditionPassed(opcode)) {
1488     uint32_t d;
1489     uint32_t n;
1490     uint32_t m;
1491     bool setflags;
1492 
1493     // EncodingSpecificOperations();
1494     switch (encoding) {
1495     case eEncodingT1:
1496       // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1497       d = Bits32(opcode, 2, 0);
1498       n = Bits32(opcode, 5, 3);
1499       m = Bits32(opcode, 2, 0);
1500       setflags = !InITBlock();
1501 
1502       // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1503       if ((ArchVersion() < ARMv6) && (d == n))
1504         return false;
1505 
1506       break;
1507 
1508     case eEncodingT2:
1509       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1510       d = Bits32(opcode, 11, 8);
1511       n = Bits32(opcode, 19, 16);
1512       m = Bits32(opcode, 3, 0);
1513       setflags = false;
1514 
1515       // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1516       if (BadReg(d) || BadReg(n) || BadReg(m))
1517         return false;
1518 
1519       break;
1520 
1521     case eEncodingA1:
1522       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1523       d = Bits32(opcode, 19, 16);
1524       n = Bits32(opcode, 3, 0);
1525       m = Bits32(opcode, 11, 8);
1526       setflags = BitIsSet(opcode, 20);
1527 
1528       // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1529       if ((d == 15) || (n == 15) || (m == 15))
1530         return false;
1531 
1532       // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1533       if ((ArchVersion() < ARMv6) && (d == n))
1534         return false;
1535 
1536       break;
1537 
1538     default:
1539       return false;
1540     }
1541 
1542     bool success = false;
1543 
1544     // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1545     // results
1546     uint64_t operand1 =
1547         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1548     if (!success)
1549       return false;
1550 
1551     // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1552     // results
1553     uint64_t operand2 =
1554         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1555     if (!success)
1556       return false;
1557 
1558     // result = operand1 * operand2;
1559     uint64_t result = operand1 * operand2;
1560 
1561     // R[d] = result<31:0>;
1562     std::optional<RegisterInfo> op1_reg =
1563         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
1564     std::optional<RegisterInfo> op2_reg =
1565         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
1566 
1567     EmulateInstruction::Context context;
1568     context.type = eContextArithmetic;
1569     context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
1570 
1571     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1572                                (0x0000ffff & result)))
1573       return false;
1574 
1575     // if setflags then
1576     if (setflags) {
1577       // APSR.N = result<31>;
1578       // APSR.Z = IsZeroBit(result);
1579       m_new_inst_cpsr = m_opcode_cpsr;
1580       SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1581       SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1582       if (m_new_inst_cpsr != m_opcode_cpsr) {
1583         if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1584                                    LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1585           return false;
1586       }
1587 
1588       // if ArchVersion() == 4 then
1589       // APSR.C = bit UNKNOWN;
1590     }
1591   }
1592   return true;
1593 }
1594 
1595 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1596 // the destination register. It can optionally update the condition flags based
1597 // on the value.
EmulateMVNImm(const uint32_t opcode,const ARMEncoding encoding)1598 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1599                                           const ARMEncoding encoding) {
1600 #if 0
1601     // ARM pseudo code...
1602     if (ConditionPassed())
1603     {
1604         EncodingSpecificOperations();
1605         result = NOT(imm32);
1606         if d == 15 then         // Can only occur for ARM encoding
1607             ALUWritePC(result); // setflags is always FALSE here
1608         else
1609             R[d] = result;
1610             if setflags then
1611                 APSR.N = result<31>;
1612                 APSR.Z = IsZeroBit(result);
1613                 APSR.C = carry;
1614                 // APSR.V unchanged
1615     }
1616 #endif
1617 
1618   if (ConditionPassed(opcode)) {
1619     uint32_t Rd;    // the destination register
1620     uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1621     uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1622     bool setflags;
1623     switch (encoding) {
1624     case eEncodingT1:
1625       Rd = Bits32(opcode, 11, 8);
1626       setflags = BitIsSet(opcode, 20);
1627       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1628       break;
1629     case eEncodingA1:
1630       Rd = Bits32(opcode, 15, 12);
1631       setflags = BitIsSet(opcode, 20);
1632       imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1633 
1634       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1635       // instructions;
1636       if (Rd == 15 && setflags)
1637         return EmulateSUBSPcLrEtc(opcode, encoding);
1638       break;
1639     default:
1640       return false;
1641     }
1642     uint32_t result = ~imm32;
1643 
1644     // The context specifies that an immediate is to be moved into Rd.
1645     EmulateInstruction::Context context;
1646     context.type = EmulateInstruction::eContextImmediate;
1647     context.SetNoArgs();
1648 
1649     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1650       return false;
1651   }
1652   return true;
1653 }
1654 
1655 // Bitwise NOT (register) writes the bitwise inverse of a register value to the
1656 // destination register. It can optionally update the condition flags based on
1657 // the result.
EmulateMVNReg(const uint32_t opcode,const ARMEncoding encoding)1658 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1659                                           const ARMEncoding encoding) {
1660 #if 0
1661     // ARM pseudo code...
1662     if (ConditionPassed())
1663     {
1664         EncodingSpecificOperations();
1665         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1666         result = NOT(shifted);
1667         if d == 15 then         // Can only occur for ARM encoding
1668             ALUWritePC(result); // setflags is always FALSE here
1669         else
1670             R[d] = result;
1671             if setflags then
1672                 APSR.N = result<31>;
1673                 APSR.Z = IsZeroBit(result);
1674                 APSR.C = carry;
1675                 // APSR.V unchanged
1676     }
1677 #endif
1678 
1679   if (ConditionPassed(opcode)) {
1680     uint32_t Rm; // the source register
1681     uint32_t Rd; // the destination register
1682     ARM_ShifterType shift_t;
1683     uint32_t shift_n; // the shift applied to the value read from Rm
1684     bool setflags;
1685     uint32_t carry; // the carry bit after the shift operation
1686     switch (encoding) {
1687     case eEncodingT1:
1688       Rd = Bits32(opcode, 2, 0);
1689       Rm = Bits32(opcode, 5, 3);
1690       setflags = !InITBlock();
1691       shift_t = SRType_LSL;
1692       shift_n = 0;
1693       if (InITBlock())
1694         return false;
1695       break;
1696     case eEncodingT2:
1697       Rd = Bits32(opcode, 11, 8);
1698       Rm = Bits32(opcode, 3, 0);
1699       setflags = BitIsSet(opcode, 20);
1700       shift_n = DecodeImmShiftThumb(opcode, shift_t);
1701       // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1702       if (BadReg(Rd) || BadReg(Rm))
1703         return false;
1704       break;
1705     case eEncodingA1:
1706       Rd = Bits32(opcode, 15, 12);
1707       Rm = Bits32(opcode, 3, 0);
1708       setflags = BitIsSet(opcode, 20);
1709       shift_n = DecodeImmShiftARM(opcode, shift_t);
1710       break;
1711     default:
1712       return false;
1713     }
1714     bool success = false;
1715     uint32_t value = ReadCoreReg(Rm, &success);
1716     if (!success)
1717       return false;
1718 
1719     uint32_t shifted =
1720         Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1721     if (!success)
1722       return false;
1723     uint32_t result = ~shifted;
1724 
1725     // The context specifies that an immediate is to be moved into Rd.
1726     EmulateInstruction::Context context;
1727     context.type = EmulateInstruction::eContextImmediate;
1728     context.SetNoArgs();
1729 
1730     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1731       return false;
1732   }
1733   return true;
1734 }
1735 
1736 // PC relative immediate load into register, possibly followed by ADD (SP plus
1737 // register).
1738 // LDR (literal)
EmulateLDRRtPCRelative(const uint32_t opcode,const ARMEncoding encoding)1739 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1740                                                    const ARMEncoding encoding) {
1741 #if 0
1742     // ARM pseudo code...
1743     if (ConditionPassed())
1744     {
1745         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1746         base = Align(PC,4);
1747         address = if add then (base + imm32) else (base - imm32);
1748         data = MemU[address,4];
1749         if t == 15 then
1750             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1751         elsif UnalignedSupport() || address<1:0> = '00' then
1752             R[t] = data;
1753         else // Can only apply before ARMv7
1754             if CurrentInstrSet() == InstrSet_ARM then
1755                 R[t] = ROR(data, 8*UInt(address<1:0>));
1756             else
1757                 R[t] = bits(32) UNKNOWN;
1758     }
1759 #endif
1760 
1761   if (ConditionPassed(opcode)) {
1762     bool success = false;
1763     const uint32_t pc = ReadCoreReg(PC_REG, &success);
1764     if (!success)
1765       return false;
1766 
1767     // PC relative immediate load context
1768     EmulateInstruction::Context context;
1769     context.type = EmulateInstruction::eContextRegisterPlusOffset;
1770     std::optional<RegisterInfo> pc_reg =
1771         GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
1772     context.SetRegisterPlusOffset(*pc_reg, 0);
1773 
1774     uint32_t Rt;    // the destination register
1775     uint32_t imm32; // immediate offset from the PC
1776     bool add;       // +imm32 or -imm32?
1777     addr_t base;    // the base address
1778     addr_t address; // the PC relative address
1779     uint32_t data;  // the literal data value from the PC relative load
1780     switch (encoding) {
1781     case eEncodingT1:
1782       Rt = Bits32(opcode, 10, 8);
1783       imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1784       add = true;
1785       break;
1786     case eEncodingT2:
1787       Rt = Bits32(opcode, 15, 12);
1788       imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1789       add = BitIsSet(opcode, 23);
1790       if (Rt == 15 && InITBlock() && !LastInITBlock())
1791         return false;
1792       break;
1793     default:
1794       return false;
1795     }
1796 
1797     base = Align(pc, 4);
1798     if (add)
1799       address = base + imm32;
1800     else
1801       address = base - imm32;
1802 
1803     context.SetRegisterPlusOffset(*pc_reg, address - base);
1804     data = MemURead(context, address, 4, 0, &success);
1805     if (!success)
1806       return false;
1807 
1808     if (Rt == 15) {
1809       if (Bits32(address, 1, 0) == 0) {
1810         // In ARMv5T and above, this is an interworking branch.
1811         if (!LoadWritePC(context, data))
1812           return false;
1813       } else
1814         return false;
1815     } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1816       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1817                                  data))
1818         return false;
1819     } else // We don't handle ARM for now.
1820       return false;
1821   }
1822   return true;
1823 }
1824 
1825 // An add operation to adjust the SP.
1826 // ADD (SP plus immediate)
EmulateADDSPImm(const uint32_t opcode,const ARMEncoding encoding)1827 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1828                                             const ARMEncoding encoding) {
1829 #if 0
1830     // ARM pseudo code...
1831     if (ConditionPassed())
1832     {
1833         EncodingSpecificOperations();
1834         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1835         if d == 15 then // Can only occur for ARM encoding
1836             ALUWritePC(result); // setflags is always FALSE here
1837         else
1838             R[d] = result;
1839             if setflags then
1840                 APSR.N = result<31>;
1841                 APSR.Z = IsZeroBit(result);
1842                 APSR.C = carry;
1843                 APSR.V = overflow;
1844     }
1845 #endif
1846 
1847   bool success = false;
1848 
1849   if (ConditionPassed(opcode)) {
1850     const addr_t sp = ReadCoreReg(SP_REG, &success);
1851     if (!success)
1852       return false;
1853     uint32_t imm32; // the immediate operand
1854     uint32_t d;
1855     bool setflags;
1856     switch (encoding) {
1857     case eEncodingT1:
1858       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1859       d = Bits32(opcode, 10, 8);
1860       imm32 = (Bits32(opcode, 7, 0) << 2);
1861       setflags = false;
1862       break;
1863 
1864     case eEncodingT2:
1865       // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1866       d = 13;
1867       imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1868       setflags = false;
1869       break;
1870 
1871     case eEncodingT3:
1872       // d = UInt(Rd); setflags = (S == "1"); imm32 =
1873       // ThumbExpandImm(i:imm3:imm8);
1874       d = Bits32(opcode, 11, 8);
1875       imm32 = ThumbExpandImm(opcode);
1876       setflags = Bit32(opcode, 20);
1877 
1878       // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1879       if (d == 15 && setflags == 1)
1880         return false; // CMN (immediate) not yet supported
1881 
1882       // if d == 15 && S == "0" then UNPREDICTABLE;
1883       if (d == 15 && setflags == 0)
1884         return false;
1885       break;
1886 
1887     case eEncodingT4: {
1888       // if Rn == '1111' then SEE ADR;
1889       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1890       d = Bits32(opcode, 11, 8);
1891       setflags = false;
1892       uint32_t i = Bit32(opcode, 26);
1893       uint32_t imm3 = Bits32(opcode, 14, 12);
1894       uint32_t imm8 = Bits32(opcode, 7, 0);
1895       imm32 = (i << 11) | (imm3 << 8) | imm8;
1896 
1897       // if d == 15 then UNPREDICTABLE;
1898       if (d == 15)
1899         return false;
1900     } break;
1901 
1902     default:
1903       return false;
1904     }
1905     // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1906     AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1907 
1908     EmulateInstruction::Context context;
1909     if (d == 13)
1910       context.type = EmulateInstruction::eContextAdjustStackPointer;
1911     else
1912       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1913 
1914     std::optional<RegisterInfo> sp_reg =
1915         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1916     context.SetRegisterPlusOffset(*sp_reg, res.result - sp);
1917 
1918     if (d == 15) {
1919       if (!ALUWritePC(context, res.result))
1920         return false;
1921     } else {
1922       // R[d] = result;
1923       // if setflags then
1924       //     APSR.N = result<31>;
1925       //     APSR.Z = IsZeroBit(result);
1926       //     APSR.C = carry;
1927       //     APSR.V = overflow;
1928       if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1929                                      res.carry_out, res.overflow))
1930         return false;
1931     }
1932   }
1933   return true;
1934 }
1935 
1936 // An add operation to adjust the SP.
1937 // ADD (SP plus register)
EmulateADDSPRm(const uint32_t opcode,const ARMEncoding encoding)1938 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1939                                            const ARMEncoding encoding) {
1940 #if 0
1941     // ARM pseudo code...
1942     if (ConditionPassed())
1943     {
1944         EncodingSpecificOperations();
1945         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1946         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1947         if d == 15 then
1948             ALUWritePC(result); // setflags is always FALSE here
1949         else
1950             R[d] = result;
1951             if setflags then
1952                 APSR.N = result<31>;
1953                 APSR.Z = IsZeroBit(result);
1954                 APSR.C = carry;
1955                 APSR.V = overflow;
1956     }
1957 #endif
1958 
1959   bool success = false;
1960 
1961   if (ConditionPassed(opcode)) {
1962     const addr_t sp = ReadCoreReg(SP_REG, &success);
1963     if (!success)
1964       return false;
1965     uint32_t Rm; // the second operand
1966     switch (encoding) {
1967     case eEncodingT2:
1968       Rm = Bits32(opcode, 6, 3);
1969       break;
1970     default:
1971       return false;
1972     }
1973     int32_t reg_value = ReadCoreReg(Rm, &success);
1974     if (!success)
1975       return false;
1976 
1977     addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1978 
1979     EmulateInstruction::Context context;
1980     context.type = eContextArithmetic;
1981     std::optional<RegisterInfo> sp_reg =
1982         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
1983     std::optional<RegisterInfo> other_reg =
1984         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
1985     context.SetRegisterRegisterOperands(*sp_reg, *other_reg);
1986 
1987     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1988                                LLDB_REGNUM_GENERIC_SP, addr))
1989       return false;
1990   }
1991   return true;
1992 }
1993 
1994 // Branch with Link and Exchange Instruction Sets (immediate) calls a
1995 // subroutine at a PC-relative address, and changes instruction set from ARM to
1996 // Thumb, or from Thumb to ARM.
1997 // BLX (immediate)
EmulateBLXImmediate(const uint32_t opcode,const ARMEncoding encoding)1998 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
1999                                                 const ARMEncoding encoding) {
2000 #if 0
2001     // ARM pseudo code...
2002     if (ConditionPassed())
2003     {
2004         EncodingSpecificOperations();
2005         if CurrentInstrSet() == InstrSet_ARM then
2006             LR = PC - 4;
2007         else
2008             LR = PC<31:1> : '1';
2009         if targetInstrSet == InstrSet_ARM then
2010             targetAddress = Align(PC,4) + imm32;
2011         else
2012             targetAddress = PC + imm32;
2013         SelectInstrSet(targetInstrSet);
2014         BranchWritePC(targetAddress);
2015     }
2016 #endif
2017 
2018   bool success = true;
2019 
2020   if (ConditionPassed(opcode)) {
2021     EmulateInstruction::Context context;
2022     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2023     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2024     if (!success)
2025       return false;
2026     addr_t lr;     // next instruction address
2027     addr_t target; // target address
2028     int32_t imm32; // PC-relative offset
2029     switch (encoding) {
2030     case eEncodingT1: {
2031       lr = pc | 1u; // return address
2032       uint32_t S = Bit32(opcode, 26);
2033       uint32_t imm10 = Bits32(opcode, 25, 16);
2034       uint32_t J1 = Bit32(opcode, 13);
2035       uint32_t J2 = Bit32(opcode, 11);
2036       uint32_t imm11 = Bits32(opcode, 10, 0);
2037       uint32_t I1 = !(J1 ^ S);
2038       uint32_t I2 = !(J2 ^ S);
2039       uint32_t imm25 =
2040           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2041       imm32 = llvm::SignExtend32<25>(imm25);
2042       target = pc + imm32;
2043       SelectInstrSet(eModeThumb);
2044       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2045       if (InITBlock() && !LastInITBlock())
2046         return false;
2047       break;
2048     }
2049     case eEncodingT2: {
2050       lr = pc | 1u; // return address
2051       uint32_t S = Bit32(opcode, 26);
2052       uint32_t imm10H = Bits32(opcode, 25, 16);
2053       uint32_t J1 = Bit32(opcode, 13);
2054       uint32_t J2 = Bit32(opcode, 11);
2055       uint32_t imm10L = Bits32(opcode, 10, 1);
2056       uint32_t I1 = !(J1 ^ S);
2057       uint32_t I2 = !(J2 ^ S);
2058       uint32_t imm25 =
2059           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2060       imm32 = llvm::SignExtend32<25>(imm25);
2061       target = Align(pc, 4) + imm32;
2062       SelectInstrSet(eModeARM);
2063       context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2064       if (InITBlock() && !LastInITBlock())
2065         return false;
2066       break;
2067     }
2068     case eEncodingA1:
2069       lr = pc - 4; // return address
2070       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2071       target = Align(pc, 4) + imm32;
2072       SelectInstrSet(eModeARM);
2073       context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2074       break;
2075     case eEncodingA2:
2076       lr = pc - 4; // return address
2077       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2078                                      Bits32(opcode, 24, 24) << 1);
2079       target = pc + imm32;
2080       SelectInstrSet(eModeThumb);
2081       context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2082       break;
2083     default:
2084       return false;
2085     }
2086     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2087                                LLDB_REGNUM_GENERIC_RA, lr))
2088       return false;
2089     if (!BranchWritePC(context, target))
2090       return false;
2091     if (m_opcode_cpsr != m_new_inst_cpsr)
2092       if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2093                                  LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2094         return false;
2095   }
2096   return true;
2097 }
2098 
2099 // Branch with Link and Exchange (register) calls a subroutine at an address
2100 // and instruction set specified by a register.
2101 // BLX (register)
EmulateBLXRm(const uint32_t opcode,const ARMEncoding encoding)2102 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2103                                          const ARMEncoding encoding) {
2104 #if 0
2105     // ARM pseudo code...
2106     if (ConditionPassed())
2107     {
2108         EncodingSpecificOperations();
2109         target = R[m];
2110         if CurrentInstrSet() == InstrSet_ARM then
2111             next_instr_addr = PC - 4;
2112             LR = next_instr_addr;
2113         else
2114             next_instr_addr = PC - 2;
2115             LR = next_instr_addr<31:1> : '1';
2116         BXWritePC(target);
2117     }
2118 #endif
2119 
2120   bool success = false;
2121 
2122   if (ConditionPassed(opcode)) {
2123     EmulateInstruction::Context context;
2124     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2125     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2126     addr_t lr; // next instruction address
2127     if (!success)
2128       return false;
2129     uint32_t Rm; // the register with the target address
2130     switch (encoding) {
2131     case eEncodingT1:
2132       lr = (pc - 2) | 1u; // return address
2133       Rm = Bits32(opcode, 6, 3);
2134       // if m == 15 then UNPREDICTABLE;
2135       if (Rm == 15)
2136         return false;
2137       if (InITBlock() && !LastInITBlock())
2138         return false;
2139       break;
2140     case eEncodingA1:
2141       lr = pc - 4; // return address
2142       Rm = Bits32(opcode, 3, 0);
2143       // if m == 15 then UNPREDICTABLE;
2144       if (Rm == 15)
2145         return false;
2146       break;
2147     default:
2148       return false;
2149     }
2150     addr_t target = ReadCoreReg(Rm, &success);
2151     if (!success)
2152       return false;
2153     std::optional<RegisterInfo> dwarf_reg =
2154         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2155     context.SetRegister(*dwarf_reg);
2156     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2157                                LLDB_REGNUM_GENERIC_RA, lr))
2158       return false;
2159     if (!BXWritePC(context, target))
2160       return false;
2161   }
2162   return true;
2163 }
2164 
2165 // Branch and Exchange causes a branch to an address and instruction set
2166 // specified by a register.
EmulateBXRm(const uint32_t opcode,const ARMEncoding encoding)2167 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2168                                         const ARMEncoding encoding) {
2169 #if 0
2170     // ARM pseudo code...
2171     if (ConditionPassed())
2172     {
2173         EncodingSpecificOperations();
2174         BXWritePC(R[m]);
2175     }
2176 #endif
2177 
2178   if (ConditionPassed(opcode)) {
2179     EmulateInstruction::Context context;
2180     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2181     uint32_t Rm; // the register with the target address
2182     switch (encoding) {
2183     case eEncodingT1:
2184       Rm = Bits32(opcode, 6, 3);
2185       if (InITBlock() && !LastInITBlock())
2186         return false;
2187       break;
2188     case eEncodingA1:
2189       Rm = Bits32(opcode, 3, 0);
2190       break;
2191     default:
2192       return false;
2193     }
2194     bool success = false;
2195     addr_t target = ReadCoreReg(Rm, &success);
2196     if (!success)
2197       return false;
2198 
2199     std::optional<RegisterInfo> dwarf_reg =
2200         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2201     context.SetRegister(*dwarf_reg);
2202     if (!BXWritePC(context, target))
2203       return false;
2204   }
2205   return true;
2206 }
2207 
2208 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2209 // attempt fails, it branches to an address and instruction set specified by a
2210 // register as though it were a BX instruction.
2211 //
2212 // TODO: Emulate Jazelle architecture?
2213 //       We currently assume that switching to Jazelle state fails, thus
2214 //       treating BXJ as a BX operation.
EmulateBXJRm(const uint32_t opcode,const ARMEncoding encoding)2215 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2216                                          const ARMEncoding encoding) {
2217 #if 0
2218     // ARM pseudo code...
2219     if (ConditionPassed())
2220     {
2221         EncodingSpecificOperations();
2222         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2223             BXWritePC(R[m]);
2224         else
2225             if JazelleAcceptsExecution() then
2226                 SwitchToJazelleExecution();
2227             else
2228                 SUBARCHITECTURE_DEFINED handler call;
2229     }
2230 #endif
2231 
2232   if (ConditionPassed(opcode)) {
2233     EmulateInstruction::Context context;
2234     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2235     uint32_t Rm; // the register with the target address
2236     switch (encoding) {
2237     case eEncodingT1:
2238       Rm = Bits32(opcode, 19, 16);
2239       if (BadReg(Rm))
2240         return false;
2241       if (InITBlock() && !LastInITBlock())
2242         return false;
2243       break;
2244     case eEncodingA1:
2245       Rm = Bits32(opcode, 3, 0);
2246       if (Rm == 15)
2247         return false;
2248       break;
2249     default:
2250       return false;
2251     }
2252     bool success = false;
2253     addr_t target = ReadCoreReg(Rm, &success);
2254     if (!success)
2255       return false;
2256 
2257     std::optional<RegisterInfo> dwarf_reg =
2258         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
2259     context.SetRegister(*dwarf_reg);
2260     if (!BXWritePC(context, target))
2261       return false;
2262   }
2263   return true;
2264 }
2265 
2266 // Set r7 to point to some ip offset.
2267 // SUB (immediate)
EmulateSUBR7IPImm(const uint32_t opcode,const ARMEncoding encoding)2268 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2269                                               const ARMEncoding encoding) {
2270 #if 0
2271     // ARM pseudo code...
2272     if (ConditionPassed())
2273     {
2274         EncodingSpecificOperations();
2275         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2276         if d == 15 then // Can only occur for ARM encoding
2277            ALUWritePC(result); // setflags is always FALSE here
2278         else
2279             R[d] = result;
2280             if setflags then
2281                 APSR.N = result<31>;
2282                 APSR.Z = IsZeroBit(result);
2283                 APSR.C = carry;
2284                 APSR.V = overflow;
2285     }
2286 #endif
2287 
2288   if (ConditionPassed(opcode)) {
2289     bool success = false;
2290     const addr_t ip = ReadCoreReg(12, &success);
2291     if (!success)
2292       return false;
2293     uint32_t imm32;
2294     switch (encoding) {
2295     case eEncodingA1:
2296       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2297       break;
2298     default:
2299       return false;
2300     }
2301     addr_t ip_offset = imm32;
2302     addr_t addr = ip - ip_offset; // the adjusted ip value
2303 
2304     EmulateInstruction::Context context;
2305     context.type = EmulateInstruction::eContextRegisterPlusOffset;
2306     std::optional<RegisterInfo> dwarf_reg =
2307         GetRegisterInfo(eRegisterKindDWARF, dwarf_r12);
2308     context.SetRegisterPlusOffset(*dwarf_reg, -ip_offset);
2309 
2310     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2311       return false;
2312   }
2313   return true;
2314 }
2315 
2316 // Set ip to point to some stack offset.
2317 // SUB (SP minus immediate)
EmulateSUBIPSPImm(const uint32_t opcode,const ARMEncoding encoding)2318 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2319                                               const ARMEncoding encoding) {
2320 #if 0
2321     // ARM pseudo code...
2322     if (ConditionPassed())
2323     {
2324         EncodingSpecificOperations();
2325         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2326         if d == 15 then // Can only occur for ARM encoding
2327            ALUWritePC(result); // setflags is always FALSE here
2328         else
2329             R[d] = result;
2330             if setflags then
2331                 APSR.N = result<31>;
2332                 APSR.Z = IsZeroBit(result);
2333                 APSR.C = carry;
2334                 APSR.V = overflow;
2335     }
2336 #endif
2337 
2338   if (ConditionPassed(opcode)) {
2339     bool success = false;
2340     const addr_t sp = ReadCoreReg(SP_REG, &success);
2341     if (!success)
2342       return false;
2343     uint32_t imm32;
2344     switch (encoding) {
2345     case eEncodingA1:
2346       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2347       break;
2348     default:
2349       return false;
2350     }
2351     addr_t sp_offset = imm32;
2352     addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2353 
2354     EmulateInstruction::Context context;
2355     context.type = EmulateInstruction::eContextRegisterPlusOffset;
2356     std::optional<RegisterInfo> dwarf_reg =
2357         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
2358     context.SetRegisterPlusOffset(*dwarf_reg, -sp_offset);
2359 
2360     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2361       return false;
2362   }
2363   return true;
2364 }
2365 
2366 // This instruction subtracts an immediate value from the SP value, and writes
2367 // the result to the destination register.
2368 //
2369 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2370 // storage.
EmulateSUBSPImm(const uint32_t opcode,const ARMEncoding encoding)2371 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2372                                             const ARMEncoding encoding) {
2373 #if 0
2374     // ARM pseudo code...
2375     if (ConditionPassed())
2376     {
2377         EncodingSpecificOperations();
2378         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2379         if d == 15 then        // Can only occur for ARM encoding
2380            ALUWritePC(result); // setflags is always FALSE here
2381         else
2382             R[d] = result;
2383             if setflags then
2384                 APSR.N = result<31>;
2385                 APSR.Z = IsZeroBit(result);
2386                 APSR.C = carry;
2387                 APSR.V = overflow;
2388     }
2389 #endif
2390 
2391   bool success = false;
2392   if (ConditionPassed(opcode)) {
2393     const addr_t sp = ReadCoreReg(SP_REG, &success);
2394     if (!success)
2395       return false;
2396 
2397     uint32_t Rd;
2398     bool setflags;
2399     uint32_t imm32;
2400     switch (encoding) {
2401     case eEncodingT1:
2402       Rd = 13;
2403       setflags = false;
2404       imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2405       break;
2406     case eEncodingT2:
2407       Rd = Bits32(opcode, 11, 8);
2408       setflags = BitIsSet(opcode, 20);
2409       imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2410       if (Rd == 15 && setflags)
2411         return EmulateCMPImm(opcode, eEncodingT2);
2412       if (Rd == 15 && !setflags)
2413         return false;
2414       break;
2415     case eEncodingT3:
2416       Rd = Bits32(opcode, 11, 8);
2417       setflags = false;
2418       imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2419       if (Rd == 15)
2420         return false;
2421       break;
2422     case eEncodingA1:
2423       Rd = Bits32(opcode, 15, 12);
2424       setflags = BitIsSet(opcode, 20);
2425       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2426 
2427       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2428       // instructions;
2429       if (Rd == 15 && setflags)
2430         return EmulateSUBSPcLrEtc(opcode, encoding);
2431       break;
2432     default:
2433       return false;
2434     }
2435     AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2436 
2437     EmulateInstruction::Context context;
2438     if (Rd == 13) {
2439       uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2440                               // to negate it, or the wrong
2441       // value gets passed down to context.SetImmediateSigned.
2442       context.type = EmulateInstruction::eContextAdjustStackPointer;
2443       context.SetImmediateSigned(-imm64); // the stack pointer offset
2444     } else {
2445       context.type = EmulateInstruction::eContextImmediate;
2446       context.SetNoArgs();
2447     }
2448 
2449     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2450                                    res.carry_out, res.overflow))
2451       return false;
2452   }
2453   return true;
2454 }
2455 
2456 // A store operation to the stack that also updates the SP.
EmulateSTRRtSP(const uint32_t opcode,const ARMEncoding encoding)2457 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2458                                            const ARMEncoding encoding) {
2459 #if 0
2460     // ARM pseudo code...
2461     if (ConditionPassed())
2462     {
2463         EncodingSpecificOperations();
2464         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2465         address = if index then offset_addr else R[n];
2466         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2467         if wback then R[n] = offset_addr;
2468     }
2469 #endif
2470 
2471   bool success = false;
2472   if (ConditionPassed(opcode)) {
2473     const uint32_t addr_byte_size = GetAddressByteSize();
2474     const addr_t sp = ReadCoreReg(SP_REG, &success);
2475     if (!success)
2476       return false;
2477     uint32_t Rt; // the source register
2478     uint32_t imm12;
2479     uint32_t
2480         Rn; // This function assumes Rn is the SP, but we should verify that.
2481 
2482     bool index;
2483     bool add;
2484     bool wback;
2485     switch (encoding) {
2486     case eEncodingA1:
2487       Rt = Bits32(opcode, 15, 12);
2488       imm12 = Bits32(opcode, 11, 0);
2489       Rn = Bits32(opcode, 19, 16);
2490 
2491       if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2492         return false;
2493 
2494       index = BitIsSet(opcode, 24);
2495       add = BitIsSet(opcode, 23);
2496       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2497 
2498       if (wback && ((Rn == 15) || (Rn == Rt)))
2499         return false;
2500       break;
2501     default:
2502       return false;
2503     }
2504     addr_t offset_addr;
2505     if (add)
2506       offset_addr = sp + imm12;
2507     else
2508       offset_addr = sp - imm12;
2509 
2510     addr_t addr;
2511     if (index)
2512       addr = offset_addr;
2513     else
2514       addr = sp;
2515 
2516     EmulateInstruction::Context context;
2517     context.type = EmulateInstruction::eContextPushRegisterOnStack;
2518     std::optional<RegisterInfo> sp_reg =
2519         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
2520     std::optional<RegisterInfo> dwarf_reg =
2521         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt);
2522 
2523     context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2524     if (Rt != 15) {
2525       uint32_t reg_value = ReadCoreReg(Rt, &success);
2526       if (!success)
2527         return false;
2528       if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2529         return false;
2530     } else {
2531       const uint32_t pc = ReadCoreReg(PC_REG, &success);
2532       if (!success)
2533         return false;
2534       if (!MemUWrite(context, addr, pc, addr_byte_size))
2535         return false;
2536     }
2537 
2538     if (wback) {
2539       context.type = EmulateInstruction::eContextAdjustStackPointer;
2540       context.SetImmediateSigned(addr - sp);
2541       if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2542                                  LLDB_REGNUM_GENERIC_SP, offset_addr))
2543         return false;
2544     }
2545   }
2546   return true;
2547 }
2548 
2549 // Vector Push stores multiple extension registers to the stack. It also
2550 // updates SP to point to the start of the stored data.
EmulateVPUSH(const uint32_t opcode,const ARMEncoding encoding)2551 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2552                                          const ARMEncoding encoding) {
2553 #if 0
2554     // ARM pseudo code...
2555     if (ConditionPassed())
2556     {
2557         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2558         address = SP - imm32;
2559         SP = SP - imm32;
2560         if single_regs then
2561             for r = 0 to regs-1
2562                 MemA[address,4] = S[d+r]; address = address+4;
2563         else
2564             for r = 0 to regs-1
2565                 // Store as two word-aligned words in the correct order for
2566                 // current endianness.
2567                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2568                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2569                 address = address+8;
2570     }
2571 #endif
2572 
2573   bool success = false;
2574   if (ConditionPassed(opcode)) {
2575     const uint32_t addr_byte_size = GetAddressByteSize();
2576     const addr_t sp = ReadCoreReg(SP_REG, &success);
2577     if (!success)
2578       return false;
2579     bool single_regs;
2580     uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2581     uint32_t imm32; // stack offset
2582     uint32_t regs;  // number of registers
2583     switch (encoding) {
2584     case eEncodingT1:
2585     case eEncodingA1:
2586       single_regs = false;
2587       d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2588       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2589       // If UInt(imm8) is odd, see "FSTMX".
2590       regs = Bits32(opcode, 7, 0) / 2;
2591       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2592       if (regs == 0 || regs > 16 || (d + regs) > 32)
2593         return false;
2594       break;
2595     case eEncodingT2:
2596     case eEncodingA2:
2597       single_regs = true;
2598       d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2599       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2600       regs = Bits32(opcode, 7, 0);
2601       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2602       if (regs == 0 || regs > 16 || (d + regs) > 32)
2603         return false;
2604       break;
2605     default:
2606       return false;
2607     }
2608     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2609     uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2610     addr_t sp_offset = imm32;
2611     addr_t addr = sp - sp_offset;
2612     uint32_t i;
2613 
2614     EmulateInstruction::Context context;
2615     context.type = EmulateInstruction::eContextPushRegisterOnStack;
2616 
2617     std::optional<RegisterInfo> sp_reg =
2618         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
2619     for (i = 0; i < regs; ++i) {
2620       std::optional<RegisterInfo> dwarf_reg =
2621           GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2622       context.SetRegisterToRegisterPlusOffset(*dwarf_reg, *sp_reg, addr - sp);
2623       // uint64_t to accommodate 64-bit registers.
2624       uint64_t reg_value = ReadRegisterUnsigned(*dwarf_reg, 0, &success);
2625       if (!success)
2626         return false;
2627       if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2628         return false;
2629       addr += reg_byte_size;
2630     }
2631 
2632     context.type = EmulateInstruction::eContextAdjustStackPointer;
2633     context.SetImmediateSigned(-sp_offset);
2634 
2635     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2636                                LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2637       return false;
2638   }
2639   return true;
2640 }
2641 
2642 // Vector Pop loads multiple extension registers from the stack. It also
2643 // updates SP to point just above the loaded data.
EmulateVPOP(const uint32_t opcode,const ARMEncoding encoding)2644 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2645                                         const ARMEncoding encoding) {
2646 #if 0
2647     // ARM pseudo code...
2648     if (ConditionPassed())
2649     {
2650         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2651         address = SP;
2652         SP = SP + imm32;
2653         if single_regs then
2654             for r = 0 to regs-1
2655                 S[d+r] = MemA[address,4]; address = address+4;
2656         else
2657             for r = 0 to regs-1
2658                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2659                 // Combine the word-aligned words in the correct order for
2660                 // current endianness.
2661                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2662     }
2663 #endif
2664 
2665   bool success = false;
2666   if (ConditionPassed(opcode)) {
2667     const uint32_t addr_byte_size = GetAddressByteSize();
2668     const addr_t sp = ReadCoreReg(SP_REG, &success);
2669     if (!success)
2670       return false;
2671     bool single_regs;
2672     uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2673     uint32_t imm32; // stack offset
2674     uint32_t regs;  // number of registers
2675     switch (encoding) {
2676     case eEncodingT1:
2677     case eEncodingA1:
2678       single_regs = false;
2679       d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2680       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2681       // If UInt(imm8) is odd, see "FLDMX".
2682       regs = Bits32(opcode, 7, 0) / 2;
2683       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2684       if (regs == 0 || regs > 16 || (d + regs) > 32)
2685         return false;
2686       break;
2687     case eEncodingT2:
2688     case eEncodingA2:
2689       single_regs = true;
2690       d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2691       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2692       regs = Bits32(opcode, 7, 0);
2693       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2694       if (regs == 0 || regs > 16 || (d + regs) > 32)
2695         return false;
2696       break;
2697     default:
2698       return false;
2699     }
2700     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2701     uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2702     addr_t sp_offset = imm32;
2703     addr_t addr = sp;
2704     uint32_t i;
2705     uint64_t data; // uint64_t to accommodate 64-bit registers.
2706 
2707     EmulateInstruction::Context context;
2708     context.type = EmulateInstruction::eContextPopRegisterOffStack;
2709 
2710     for (i = 0; i < regs; ++i) {
2711       std::optional<RegisterInfo> dwarf_reg =
2712           GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i);
2713       context.SetAddress(addr);
2714       data = MemARead(context, addr, reg_byte_size, 0, &success);
2715       if (!success)
2716         return false;
2717       if (!WriteRegisterUnsigned(context, *dwarf_reg, data))
2718         return false;
2719       addr += reg_byte_size;
2720     }
2721 
2722     context.type = EmulateInstruction::eContextAdjustStackPointer;
2723     context.SetImmediateSigned(sp_offset);
2724 
2725     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2726                                LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2727       return false;
2728   }
2729   return true;
2730 }
2731 
2732 // SVC (previously SWI)
EmulateSVC(const uint32_t opcode,const ARMEncoding encoding)2733 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2734                                        const ARMEncoding encoding) {
2735 #if 0
2736     // ARM pseudo code...
2737     if (ConditionPassed())
2738     {
2739         EncodingSpecificOperations();
2740         CallSupervisor();
2741     }
2742 #endif
2743 
2744   bool success = false;
2745 
2746   if (ConditionPassed(opcode)) {
2747     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2748     addr_t lr; // next instruction address
2749     if (!success)
2750       return false;
2751     uint32_t imm32; // the immediate constant
2752     uint32_t mode;  // ARM or Thumb mode
2753     switch (encoding) {
2754     case eEncodingT1:
2755       lr = (pc + 2) | 1u; // return address
2756       imm32 = Bits32(opcode, 7, 0);
2757       mode = eModeThumb;
2758       break;
2759     case eEncodingA1:
2760       lr = pc + 4; // return address
2761       imm32 = Bits32(opcode, 23, 0);
2762       mode = eModeARM;
2763       break;
2764     default:
2765       return false;
2766     }
2767 
2768     EmulateInstruction::Context context;
2769     context.type = EmulateInstruction::eContextSupervisorCall;
2770     context.SetISAAndImmediate(mode, imm32);
2771     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2772                                LLDB_REGNUM_GENERIC_RA, lr))
2773       return false;
2774   }
2775   return true;
2776 }
2777 
2778 // If Then makes up to four following instructions (the IT block) conditional.
EmulateIT(const uint32_t opcode,const ARMEncoding encoding)2779 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2780                                       const ARMEncoding encoding) {
2781 #if 0
2782     // ARM pseudo code...
2783     EncodingSpecificOperations();
2784     ITSTATE.IT<7:0> = firstcond:mask;
2785 #endif
2786 
2787   m_it_session.InitIT(Bits32(opcode, 7, 0));
2788   return true;
2789 }
2790 
EmulateNop(const uint32_t opcode,const ARMEncoding encoding)2791 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2792                                        const ARMEncoding encoding) {
2793   // NOP, nothing to do...
2794   return true;
2795 }
2796 
2797 // Branch causes a branch to a target address.
EmulateB(const uint32_t opcode,const ARMEncoding encoding)2798 bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2799                                      const ARMEncoding encoding) {
2800 #if 0
2801     // ARM pseudo code...
2802     if (ConditionPassed())
2803     {
2804         EncodingSpecificOperations();
2805         BranchWritePC(PC + imm32);
2806     }
2807 #endif
2808 
2809   bool success = false;
2810 
2811   if (ConditionPassed(opcode)) {
2812     EmulateInstruction::Context context;
2813     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2814     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2815     if (!success)
2816       return false;
2817     addr_t target; // target address
2818     int32_t imm32; // PC-relative offset
2819     switch (encoding) {
2820     case eEncodingT1:
2821       // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2822       imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2823       target = pc + imm32;
2824       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2825       break;
2826     case eEncodingT2:
2827       imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2828       target = pc + imm32;
2829       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2830       break;
2831     case eEncodingT3:
2832       // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2833       {
2834         if (Bits32(opcode, 25, 23) == 7)
2835           return false; // See Branches and miscellaneous control on page
2836                         // A6-235.
2837 
2838         uint32_t S = Bit32(opcode, 26);
2839         uint32_t imm6 = Bits32(opcode, 21, 16);
2840         uint32_t J1 = Bit32(opcode, 13);
2841         uint32_t J2 = Bit32(opcode, 11);
2842         uint32_t imm11 = Bits32(opcode, 10, 0);
2843         uint32_t imm21 =
2844             (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2845         imm32 = llvm::SignExtend32<21>(imm21);
2846         target = pc + imm32;
2847         context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2848         break;
2849       }
2850     case eEncodingT4: {
2851       uint32_t S = Bit32(opcode, 26);
2852       uint32_t imm10 = Bits32(opcode, 25, 16);
2853       uint32_t J1 = Bit32(opcode, 13);
2854       uint32_t J2 = Bit32(opcode, 11);
2855       uint32_t imm11 = Bits32(opcode, 10, 0);
2856       uint32_t I1 = !(J1 ^ S);
2857       uint32_t I2 = !(J2 ^ S);
2858       uint32_t imm25 =
2859           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2860       imm32 = llvm::SignExtend32<25>(imm25);
2861       target = pc + imm32;
2862       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2863       break;
2864     }
2865     case eEncodingA1:
2866       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2867       target = pc + imm32;
2868       context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2869       break;
2870     default:
2871       return false;
2872     }
2873     if (!BranchWritePC(context, target))
2874       return false;
2875   }
2876   return true;
2877 }
2878 
2879 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2880 // value in a register with zero and conditionally branch forward a constant
2881 // value.  They do not affect the condition flags. CBNZ, CBZ
EmulateCB(const uint32_t opcode,const ARMEncoding encoding)2882 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2883                                       const ARMEncoding encoding) {
2884 #if 0
2885     // ARM pseudo code...
2886     EncodingSpecificOperations();
2887     if nonzero ^ IsZero(R[n]) then
2888         BranchWritePC(PC + imm32);
2889 #endif
2890 
2891   bool success = false;
2892 
2893   // Read the register value from the operand register Rn.
2894   uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2895   if (!success)
2896     return false;
2897 
2898   EmulateInstruction::Context context;
2899   context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2900   const uint32_t pc = ReadCoreReg(PC_REG, &success);
2901   if (!success)
2902     return false;
2903 
2904   addr_t target;  // target address
2905   uint32_t imm32; // PC-relative offset to branch forward
2906   bool nonzero;
2907   switch (encoding) {
2908   case eEncodingT1:
2909     imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2910     nonzero = BitIsSet(opcode, 11);
2911     target = pc + imm32;
2912     context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2913     break;
2914   default:
2915     return false;
2916   }
2917   if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2918     if (!BranchWritePC(context, target))
2919       return false;
2920 
2921   return true;
2922 }
2923 
2924 // Table Branch Byte causes a PC-relative forward branch using a table of
2925 // single byte offsets.
2926 // A base register provides a pointer to the table, and a second register
2927 // supplies an index into the table.
2928 // The branch length is twice the value of the byte returned from the table.
2929 //
2930 // Table Branch Halfword causes a PC-relative forward branch using a table of
2931 // single halfword offsets.
2932 // A base register provides a pointer to the table, and a second register
2933 // supplies an index into the table.
2934 // The branch length is twice the value of the halfword returned from the
2935 // table. TBB, TBH
EmulateTB(const uint32_t opcode,const ARMEncoding encoding)2936 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2937                                       const ARMEncoding encoding) {
2938 #if 0
2939     // ARM pseudo code...
2940     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2941     if is_tbh then
2942         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2943     else
2944         halfwords = UInt(MemU[R[n]+R[m], 1]);
2945     BranchWritePC(PC + 2*halfwords);
2946 #endif
2947 
2948   bool success = false;
2949 
2950   if (ConditionPassed(opcode)) {
2951     uint32_t Rn; // the base register which contains the address of the table of
2952                  // branch lengths
2953     uint32_t Rm; // the index register which contains an integer pointing to a
2954                  // byte/halfword in the table
2955     bool is_tbh; // true if table branch halfword
2956     switch (encoding) {
2957     case eEncodingT1:
2958       Rn = Bits32(opcode, 19, 16);
2959       Rm = Bits32(opcode, 3, 0);
2960       is_tbh = BitIsSet(opcode, 4);
2961       if (Rn == 13 || BadReg(Rm))
2962         return false;
2963       if (InITBlock() && !LastInITBlock())
2964         return false;
2965       break;
2966     default:
2967       return false;
2968     }
2969 
2970     // Read the address of the table from the operand register Rn. The PC can
2971     // be used, in which case the table immediately follows this instruction.
2972     uint32_t base = ReadCoreReg(Rn, &success);
2973     if (!success)
2974       return false;
2975 
2976     // the table index
2977     uint32_t index = ReadCoreReg(Rm, &success);
2978     if (!success)
2979       return false;
2980 
2981     // the offsetted table address
2982     addr_t addr = base + (is_tbh ? index * 2 : index);
2983 
2984     // PC-relative offset to branch forward
2985     EmulateInstruction::Context context;
2986     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2987     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2988     if (!success)
2989       return false;
2990 
2991     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2992     if (!success)
2993       return false;
2994 
2995     // target address
2996     addr_t target = pc + offset;
2997     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2998     context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
2999 
3000     if (!BranchWritePC(context, target))
3001       return false;
3002   }
3003 
3004   return true;
3005 }
3006 
3007 // This instruction adds an immediate value to a register value, and writes the
3008 // result to the destination register. It can optionally update the condition
3009 // flags based on the result.
EmulateADDImmThumb(const uint32_t opcode,const ARMEncoding encoding)3010 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3011                                                const ARMEncoding encoding) {
3012 #if 0
3013     if ConditionPassed() then
3014         EncodingSpecificOperations();
3015         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3016         R[d] = result;
3017         if setflags then
3018             APSR.N = result<31>;
3019             APSR.Z = IsZeroBit(result);
3020             APSR.C = carry;
3021             APSR.V = overflow;
3022 #endif
3023 
3024   bool success = false;
3025 
3026   if (ConditionPassed(opcode)) {
3027     uint32_t d;
3028     uint32_t n;
3029     bool setflags;
3030     uint32_t imm32;
3031     uint32_t carry_out;
3032 
3033     // EncodingSpecificOperations();
3034     switch (encoding) {
3035     case eEncodingT1:
3036       // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3037       // ZeroExtend(imm3, 32);
3038       d = Bits32(opcode, 2, 0);
3039       n = Bits32(opcode, 5, 3);
3040       setflags = !InITBlock();
3041       imm32 = Bits32(opcode, 8, 6);
3042 
3043       break;
3044 
3045     case eEncodingT2:
3046       // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3047       // ZeroExtend(imm8, 32);
3048       d = Bits32(opcode, 10, 8);
3049       n = Bits32(opcode, 10, 8);
3050       setflags = !InITBlock();
3051       imm32 = Bits32(opcode, 7, 0);
3052 
3053       break;
3054 
3055     case eEncodingT3:
3056       // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3057       // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3058       // ThumbExpandImm(i:imm3:imm8);
3059       d = Bits32(opcode, 11, 8);
3060       n = Bits32(opcode, 19, 16);
3061       setflags = BitIsSet(opcode, 20);
3062       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3063 
3064       // if Rn == '1101' then SEE ADD (SP plus immediate);
3065       if (n == 13)
3066         return EmulateADDSPImm(opcode, eEncodingT3);
3067 
3068       // if BadReg(d) || n == 15 then UNPREDICTABLE;
3069       if (BadReg(d) || (n == 15))
3070         return false;
3071 
3072       break;
3073 
3074     case eEncodingT4: {
3075       // if Rn == '1111' then SEE ADR;
3076       // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3077       // ZeroExtend(i:imm3:imm8, 32);
3078       d = Bits32(opcode, 11, 8);
3079       n = Bits32(opcode, 19, 16);
3080       setflags = false;
3081       uint32_t i = Bit32(opcode, 26);
3082       uint32_t imm3 = Bits32(opcode, 14, 12);
3083       uint32_t imm8 = Bits32(opcode, 7, 0);
3084       imm32 = (i << 11) | (imm3 << 8) | imm8;
3085 
3086       // if Rn == '1101' then SEE ADD (SP plus immediate);
3087       if (n == 13)
3088         return EmulateADDSPImm(opcode, eEncodingT4);
3089 
3090       // if BadReg(d) then UNPREDICTABLE;
3091       if (BadReg(d))
3092         return false;
3093 
3094       break;
3095     }
3096 
3097     default:
3098       return false;
3099     }
3100 
3101     uint64_t Rn =
3102         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3103     if (!success)
3104       return false;
3105 
3106     //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3107     AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3108 
3109     std::optional<RegisterInfo> reg_n =
3110         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
3111     EmulateInstruction::Context context;
3112     context.type = eContextArithmetic;
3113     context.SetRegisterPlusOffset(*reg_n, imm32);
3114 
3115     // R[d] = result;
3116     // if setflags then
3117     // APSR.N = result<31>;
3118     // APSR.Z = IsZeroBit(result);
3119     // APSR.C = carry;
3120     // APSR.V = overflow;
3121     if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3122                                    res.carry_out, res.overflow))
3123       return false;
3124   }
3125   return true;
3126 }
3127 
3128 // This instruction adds an immediate value to a register value, and writes the
3129 // result to the destination register.  It can optionally update the condition
3130 // flags based on the result.
EmulateADDImmARM(const uint32_t opcode,const ARMEncoding encoding)3131 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3132                                              const ARMEncoding encoding) {
3133 #if 0
3134     // ARM pseudo code...
3135     if ConditionPassed() then
3136         EncodingSpecificOperations();
3137         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3138         if d == 15 then
3139             ALUWritePC(result); // setflags is always FALSE here
3140         else
3141             R[d] = result;
3142             if setflags then
3143                 APSR.N = result<31>;
3144                 APSR.Z = IsZeroBit(result);
3145                 APSR.C = carry;
3146                 APSR.V = overflow;
3147 #endif
3148 
3149   bool success = false;
3150 
3151   if (ConditionPassed(opcode)) {
3152     uint32_t Rd, Rn;
3153     uint32_t
3154         imm32; // the immediate value to be added to the value obtained from Rn
3155     bool setflags;
3156     switch (encoding) {
3157     case eEncodingA1:
3158       Rd = Bits32(opcode, 15, 12);
3159       Rn = Bits32(opcode, 19, 16);
3160       setflags = BitIsSet(opcode, 20);
3161       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3162       break;
3163     default:
3164       return false;
3165     }
3166 
3167     // Read the first operand.
3168     uint32_t val1 = ReadCoreReg(Rn, &success);
3169     if (!success)
3170       return false;
3171 
3172     AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3173 
3174     EmulateInstruction::Context context;
3175     if (Rd == 13)
3176       context.type = EmulateInstruction::eContextAdjustStackPointer;
3177     else if (Rd == GetFramePointerRegisterNumber())
3178       context.type = EmulateInstruction::eContextSetFramePointer;
3179     else
3180       context.type = EmulateInstruction::eContextRegisterPlusOffset;
3181 
3182     std::optional<RegisterInfo> dwarf_reg =
3183         GetRegisterInfo(eRegisterKindDWARF, Rn);
3184     context.SetRegisterPlusOffset(*dwarf_reg, imm32);
3185 
3186     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3187                                    res.carry_out, res.overflow))
3188       return false;
3189   }
3190   return true;
3191 }
3192 
3193 // This instruction adds a register value and an optionally-shifted register
3194 // value, and writes the result to the destination register. It can optionally
3195 // update the condition flags based on the result.
EmulateADDReg(const uint32_t opcode,const ARMEncoding encoding)3196 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3197                                           const ARMEncoding encoding) {
3198 #if 0
3199     // ARM pseudo code...
3200     if ConditionPassed() then
3201         EncodingSpecificOperations();
3202         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3203         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3204         if d == 15 then
3205             ALUWritePC(result); // setflags is always FALSE here
3206         else
3207             R[d] = result;
3208             if setflags then
3209                 APSR.N = result<31>;
3210                 APSR.Z = IsZeroBit(result);
3211                 APSR.C = carry;
3212                 APSR.V = overflow;
3213 #endif
3214 
3215   bool success = false;
3216 
3217   if (ConditionPassed(opcode)) {
3218     uint32_t Rd, Rn, Rm;
3219     ARM_ShifterType shift_t;
3220     uint32_t shift_n; // the shift applied to the value read from Rm
3221     bool setflags;
3222     switch (encoding) {
3223     case eEncodingT1:
3224       Rd = Bits32(opcode, 2, 0);
3225       Rn = Bits32(opcode, 5, 3);
3226       Rm = Bits32(opcode, 8, 6);
3227       setflags = !InITBlock();
3228       shift_t = SRType_LSL;
3229       shift_n = 0;
3230       break;
3231     case eEncodingT2:
3232       Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3233       Rm = Bits32(opcode, 6, 3);
3234       setflags = false;
3235       shift_t = SRType_LSL;
3236       shift_n = 0;
3237       if (Rn == 15 && Rm == 15)
3238         return false;
3239       if (Rd == 15 && InITBlock() && !LastInITBlock())
3240         return false;
3241       break;
3242     case eEncodingA1:
3243       Rd = Bits32(opcode, 15, 12);
3244       Rn = Bits32(opcode, 19, 16);
3245       Rm = Bits32(opcode, 3, 0);
3246       setflags = BitIsSet(opcode, 20);
3247       shift_n = DecodeImmShiftARM(opcode, shift_t);
3248       break;
3249     default:
3250       return false;
3251     }
3252 
3253     // Read the first operand.
3254     uint32_t val1 = ReadCoreReg(Rn, &success);
3255     if (!success)
3256       return false;
3257 
3258     // Read the second operand.
3259     uint32_t val2 = ReadCoreReg(Rm, &success);
3260     if (!success)
3261       return false;
3262 
3263     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3264     if (!success)
3265       return false;
3266     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3267 
3268     EmulateInstruction::Context context;
3269     context.type = eContextArithmetic;
3270     std::optional<RegisterInfo> op1_reg =
3271         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn);
3272     std::optional<RegisterInfo> op2_reg =
3273         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm);
3274     context.SetRegisterRegisterOperands(*op1_reg, *op2_reg);
3275 
3276     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3277                                    res.carry_out, res.overflow))
3278       return false;
3279   }
3280   return true;
3281 }
3282 
3283 // Compare Negative (immediate) adds a register value and an immediate value.
3284 // It updates the condition flags based on the result, and discards the result.
EmulateCMNImm(const uint32_t opcode,const ARMEncoding encoding)3285 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3286                                           const ARMEncoding encoding) {
3287 #if 0
3288     // ARM pseudo code...
3289     if ConditionPassed() then
3290         EncodingSpecificOperations();
3291         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3292         APSR.N = result<31>;
3293         APSR.Z = IsZeroBit(result);
3294         APSR.C = carry;
3295         APSR.V = overflow;
3296 #endif
3297 
3298   bool success = false;
3299 
3300   uint32_t Rn;    // the first operand
3301   uint32_t imm32; // the immediate value to be compared with
3302   switch (encoding) {
3303   case eEncodingT1:
3304     Rn = Bits32(opcode, 19, 16);
3305     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3306     if (Rn == 15)
3307       return false;
3308     break;
3309   case eEncodingA1:
3310     Rn = Bits32(opcode, 19, 16);
3311     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3312     break;
3313   default:
3314     return false;
3315   }
3316   // Read the register value from the operand register Rn.
3317   uint32_t reg_val = ReadCoreReg(Rn, &success);
3318   if (!success)
3319     return false;
3320 
3321   AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3322 
3323   EmulateInstruction::Context context;
3324   context.type = EmulateInstruction::eContextImmediate;
3325   context.SetNoArgs();
3326   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3327 }
3328 
3329 // Compare Negative (register) adds a register value and an optionally-shifted
3330 // register value. It updates the condition flags based on the result, and
3331 // discards the result.
EmulateCMNReg(const uint32_t opcode,const ARMEncoding encoding)3332 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3333                                           const ARMEncoding encoding) {
3334 #if 0
3335     // ARM pseudo code...
3336     if ConditionPassed() then
3337         EncodingSpecificOperations();
3338         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3339         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3340         APSR.N = result<31>;
3341         APSR.Z = IsZeroBit(result);
3342         APSR.C = carry;
3343         APSR.V = overflow;
3344 #endif
3345 
3346   bool success = false;
3347 
3348   uint32_t Rn; // the first operand
3349   uint32_t Rm; // the second operand
3350   ARM_ShifterType shift_t;
3351   uint32_t shift_n; // the shift applied to the value read from Rm
3352   switch (encoding) {
3353   case eEncodingT1:
3354     Rn = Bits32(opcode, 2, 0);
3355     Rm = Bits32(opcode, 5, 3);
3356     shift_t = SRType_LSL;
3357     shift_n = 0;
3358     break;
3359   case eEncodingT2:
3360     Rn = Bits32(opcode, 19, 16);
3361     Rm = Bits32(opcode, 3, 0);
3362     shift_n = DecodeImmShiftThumb(opcode, shift_t);
3363     // if n == 15 || BadReg(m) then UNPREDICTABLE;
3364     if (Rn == 15 || BadReg(Rm))
3365       return false;
3366     break;
3367   case eEncodingA1:
3368     Rn = Bits32(opcode, 19, 16);
3369     Rm = Bits32(opcode, 3, 0);
3370     shift_n = DecodeImmShiftARM(opcode, shift_t);
3371     break;
3372   default:
3373     return false;
3374   }
3375   // Read the register value from register Rn.
3376   uint32_t val1 = ReadCoreReg(Rn, &success);
3377   if (!success)
3378     return false;
3379 
3380   // Read the register value from register Rm.
3381   uint32_t val2 = ReadCoreReg(Rm, &success);
3382   if (!success)
3383     return false;
3384 
3385   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3386   if (!success)
3387     return false;
3388   AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3389 
3390   EmulateInstruction::Context context;
3391   context.type = EmulateInstruction::eContextImmediate;
3392   context.SetNoArgs();
3393   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3394 }
3395 
3396 // Compare (immediate) subtracts an immediate value from a register value. It
3397 // updates the condition flags based on the result, and discards the result.
EmulateCMPImm(const uint32_t opcode,const ARMEncoding encoding)3398 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3399                                           const ARMEncoding encoding) {
3400 #if 0
3401     // ARM pseudo code...
3402     if ConditionPassed() then
3403         EncodingSpecificOperations();
3404         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3405         APSR.N = result<31>;
3406         APSR.Z = IsZeroBit(result);
3407         APSR.C = carry;
3408         APSR.V = overflow;
3409 #endif
3410 
3411   bool success = false;
3412 
3413   uint32_t Rn;    // the first operand
3414   uint32_t imm32; // the immediate value to be compared with
3415   switch (encoding) {
3416   case eEncodingT1:
3417     Rn = Bits32(opcode, 10, 8);
3418     imm32 = Bits32(opcode, 7, 0);
3419     break;
3420   case eEncodingT2:
3421     Rn = Bits32(opcode, 19, 16);
3422     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3423     if (Rn == 15)
3424       return false;
3425     break;
3426   case eEncodingA1:
3427     Rn = Bits32(opcode, 19, 16);
3428     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3429     break;
3430   default:
3431     return false;
3432   }
3433   // Read the register value from the operand register Rn.
3434   uint32_t reg_val = ReadCoreReg(Rn, &success);
3435   if (!success)
3436     return false;
3437 
3438   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3439 
3440   EmulateInstruction::Context context;
3441   context.type = EmulateInstruction::eContextImmediate;
3442   context.SetNoArgs();
3443   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3444 }
3445 
3446 // Compare (register) subtracts an optionally-shifted register value from a
3447 // register value. It updates the condition flags based on the result, and
3448 // discards the result.
EmulateCMPReg(const uint32_t opcode,const ARMEncoding encoding)3449 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3450                                           const ARMEncoding encoding) {
3451 #if 0
3452     // ARM pseudo code...
3453     if ConditionPassed() then
3454         EncodingSpecificOperations();
3455         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3456         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3457         APSR.N = result<31>;
3458         APSR.Z = IsZeroBit(result);
3459         APSR.C = carry;
3460         APSR.V = overflow;
3461 #endif
3462 
3463   bool success = false;
3464 
3465   uint32_t Rn; // the first operand
3466   uint32_t Rm; // the second operand
3467   ARM_ShifterType shift_t;
3468   uint32_t shift_n; // the shift applied to the value read from Rm
3469   switch (encoding) {
3470   case eEncodingT1:
3471     Rn = Bits32(opcode, 2, 0);
3472     Rm = Bits32(opcode, 5, 3);
3473     shift_t = SRType_LSL;
3474     shift_n = 0;
3475     break;
3476   case eEncodingT2:
3477     Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3478     Rm = Bits32(opcode, 6, 3);
3479     shift_t = SRType_LSL;
3480     shift_n = 0;
3481     if (Rn < 8 && Rm < 8)
3482       return false;
3483     if (Rn == 15 || Rm == 15)
3484       return false;
3485     break;
3486   case eEncodingT3:
3487     Rn = Bits32(opcode, 19, 16);
3488     Rm = Bits32(opcode, 3, 0);
3489     shift_n = DecodeImmShiftThumb(opcode, shift_t);
3490     if (Rn == 15 || BadReg(Rm))
3491       return false;
3492     break;
3493   case eEncodingA1:
3494     Rn = Bits32(opcode, 19, 16);
3495     Rm = Bits32(opcode, 3, 0);
3496     shift_n = DecodeImmShiftARM(opcode, shift_t);
3497     break;
3498   default:
3499     return false;
3500   }
3501   // Read the register value from register Rn.
3502   uint32_t val1 = ReadCoreReg(Rn, &success);
3503   if (!success)
3504     return false;
3505 
3506   // Read the register value from register Rm.
3507   uint32_t val2 = ReadCoreReg(Rm, &success);
3508   if (!success)
3509     return false;
3510 
3511   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3512   if (!success)
3513     return false;
3514   AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3515 
3516   EmulateInstruction::Context context;
3517   context.type = EmulateInstruction::eContextImmediate;
3518   context.SetNoArgs();
3519   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3520 }
3521 
3522 // Arithmetic Shift Right (immediate) shifts a register value right by an
3523 // immediate number of bits, shifting in copies of its sign bit, and writes the
3524 // result to the destination register.  It can optionally update the condition
3525 // flags based on the result.
EmulateASRImm(const uint32_t opcode,const ARMEncoding encoding)3526 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3527                                           const ARMEncoding encoding) {
3528 #if 0
3529     // ARM pseudo code...
3530     if ConditionPassed() then
3531         EncodingSpecificOperations();
3532         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3533         if d == 15 then         // Can only occur for ARM encoding
3534             ALUWritePC(result); // setflags is always FALSE here
3535         else
3536             R[d] = result;
3537             if setflags then
3538                 APSR.N = result<31>;
3539                 APSR.Z = IsZeroBit(result);
3540                 APSR.C = carry;
3541                 // APSR.V unchanged
3542 #endif
3543 
3544   return EmulateShiftImm(opcode, encoding, SRType_ASR);
3545 }
3546 
3547 // Arithmetic Shift Right (register) shifts a register value right by a
3548 // variable number of bits, shifting in copies of its sign bit, and writes the
3549 // result to the destination register. The variable number of bits is read from
3550 // the bottom byte of a register. It can optionally update the condition flags
3551 // based on the result.
EmulateASRReg(const uint32_t opcode,const ARMEncoding encoding)3552 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3553                                           const ARMEncoding encoding) {
3554 #if 0
3555     // ARM pseudo code...
3556     if ConditionPassed() then
3557         EncodingSpecificOperations();
3558         shift_n = UInt(R[m]<7:0>);
3559         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3560         R[d] = result;
3561         if setflags then
3562             APSR.N = result<31>;
3563             APSR.Z = IsZeroBit(result);
3564             APSR.C = carry;
3565             // APSR.V unchanged
3566 #endif
3567 
3568   return EmulateShiftReg(opcode, encoding, SRType_ASR);
3569 }
3570 
3571 // Logical Shift Left (immediate) shifts a register value left by an immediate
3572 // number of bits, shifting in zeros, and writes the result to the destination
3573 // register.  It can optionally update the condition flags based on the result.
EmulateLSLImm(const uint32_t opcode,const ARMEncoding encoding)3574 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3575                                           const ARMEncoding encoding) {
3576 #if 0
3577     // ARM pseudo code...
3578     if ConditionPassed() then
3579         EncodingSpecificOperations();
3580         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3581         if d == 15 then         // Can only occur for ARM encoding
3582             ALUWritePC(result); // setflags is always FALSE here
3583         else
3584             R[d] = result;
3585             if setflags then
3586                 APSR.N = result<31>;
3587                 APSR.Z = IsZeroBit(result);
3588                 APSR.C = carry;
3589                 // APSR.V unchanged
3590 #endif
3591 
3592   return EmulateShiftImm(opcode, encoding, SRType_LSL);
3593 }
3594 
3595 // Logical Shift Left (register) shifts a register value left by a variable
3596 // number of bits, shifting in zeros, and writes the result to the destination
3597 // register.  The variable number of bits is read from the bottom byte of a
3598 // register. It can optionally update the condition flags based on the result.
EmulateLSLReg(const uint32_t opcode,const ARMEncoding encoding)3599 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3600                                           const ARMEncoding encoding) {
3601 #if 0
3602     // ARM pseudo code...
3603     if ConditionPassed() then
3604         EncodingSpecificOperations();
3605         shift_n = UInt(R[m]<7:0>);
3606         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3607         R[d] = result;
3608         if setflags then
3609             APSR.N = result<31>;
3610             APSR.Z = IsZeroBit(result);
3611             APSR.C = carry;
3612             // APSR.V unchanged
3613 #endif
3614 
3615   return EmulateShiftReg(opcode, encoding, SRType_LSL);
3616 }
3617 
3618 // Logical Shift Right (immediate) shifts a register value right by an
3619 // immediate number of bits, shifting in zeros, and writes the result to the
3620 // destination register.  It can optionally update the condition flags based on
3621 // the result.
EmulateLSRImm(const uint32_t opcode,const ARMEncoding encoding)3622 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3623                                           const ARMEncoding encoding) {
3624 #if 0
3625     // ARM pseudo code...
3626     if ConditionPassed() then
3627         EncodingSpecificOperations();
3628         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3629         if d == 15 then         // Can only occur for ARM encoding
3630             ALUWritePC(result); // setflags is always FALSE here
3631         else
3632             R[d] = result;
3633             if setflags then
3634                 APSR.N = result<31>;
3635                 APSR.Z = IsZeroBit(result);
3636                 APSR.C = carry;
3637                 // APSR.V unchanged
3638 #endif
3639 
3640   return EmulateShiftImm(opcode, encoding, SRType_LSR);
3641 }
3642 
3643 // Logical Shift Right (register) shifts a register value right by a variable
3644 // number of bits, shifting in zeros, and writes the result to the destination
3645 // register.  The variable number of bits is read from the bottom byte of a
3646 // register. It can optionally update the condition flags based on the result.
EmulateLSRReg(const uint32_t opcode,const ARMEncoding encoding)3647 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3648                                           const ARMEncoding encoding) {
3649 #if 0
3650     // ARM pseudo code...
3651     if ConditionPassed() then
3652         EncodingSpecificOperations();
3653         shift_n = UInt(R[m]<7:0>);
3654         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3655         R[d] = result;
3656         if setflags then
3657             APSR.N = result<31>;
3658             APSR.Z = IsZeroBit(result);
3659             APSR.C = carry;
3660             // APSR.V unchanged
3661 #endif
3662 
3663   return EmulateShiftReg(opcode, encoding, SRType_LSR);
3664 }
3665 
3666 // Rotate Right (immediate) provides the value of the contents of a register
3667 // rotated by a constant value. The bits that are rotated off the right end are
3668 // inserted into the vacated bit positions on the left. It can optionally
3669 // update the condition flags based on the result.
EmulateRORImm(const uint32_t opcode,const ARMEncoding encoding)3670 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3671                                           const ARMEncoding encoding) {
3672 #if 0
3673     // ARM pseudo code...
3674     if ConditionPassed() then
3675         EncodingSpecificOperations();
3676         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3677         if d == 15 then         // Can only occur for ARM encoding
3678             ALUWritePC(result); // setflags is always FALSE here
3679         else
3680             R[d] = result;
3681             if setflags then
3682                 APSR.N = result<31>;
3683                 APSR.Z = IsZeroBit(result);
3684                 APSR.C = carry;
3685                 // APSR.V unchanged
3686 #endif
3687 
3688   return EmulateShiftImm(opcode, encoding, SRType_ROR);
3689 }
3690 
3691 // Rotate Right (register) provides the value of the contents of a register
3692 // rotated by a variable number of bits. The bits that are rotated off the
3693 // right end are inserted into the vacated bit positions on the left. The
3694 // variable number of bits is read from the bottom byte of a register. It can
3695 // optionally update the condition flags based on the result.
EmulateRORReg(const uint32_t opcode,const ARMEncoding encoding)3696 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3697                                           const ARMEncoding encoding) {
3698 #if 0
3699     // ARM pseudo code...
3700     if ConditionPassed() then
3701         EncodingSpecificOperations();
3702         shift_n = UInt(R[m]<7:0>);
3703         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3704         R[d] = result;
3705         if setflags then
3706             APSR.N = result<31>;
3707             APSR.Z = IsZeroBit(result);
3708             APSR.C = carry;
3709             // APSR.V unchanged
3710 #endif
3711 
3712   return EmulateShiftReg(opcode, encoding, SRType_ROR);
3713 }
3714 
3715 // Rotate Right with Extend provides the value of the contents of a register
3716 // shifted right by one place, with the carry flag shifted into bit [31].
3717 //
3718 // RRX can optionally update the condition flags based on the result.
3719 // In that case, bit [0] is shifted into the carry flag.
EmulateRRX(const uint32_t opcode,const ARMEncoding encoding)3720 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3721                                        const ARMEncoding encoding) {
3722 #if 0
3723     // ARM pseudo code...
3724     if ConditionPassed() then
3725         EncodingSpecificOperations();
3726         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3727         if d == 15 then         // Can only occur for ARM encoding
3728             ALUWritePC(result); // setflags is always FALSE here
3729         else
3730             R[d] = result;
3731             if setflags then
3732                 APSR.N = result<31>;
3733                 APSR.Z = IsZeroBit(result);
3734                 APSR.C = carry;
3735                 // APSR.V unchanged
3736 #endif
3737 
3738   return EmulateShiftImm(opcode, encoding, SRType_RRX);
3739 }
3740 
EmulateShiftImm(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3741 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3742                                             const ARMEncoding encoding,
3743                                             ARM_ShifterType shift_type) {
3744   //    assert(shift_type == SRType_ASR
3745   //           || shift_type == SRType_LSL
3746   //           || shift_type == SRType_LSR
3747   //           || shift_type == SRType_ROR
3748   //           || shift_type == SRType_RRX);
3749 
3750   bool success = false;
3751 
3752   if (ConditionPassed(opcode)) {
3753     uint32_t Rd;    // the destination register
3754     uint32_t Rm;    // the first operand register
3755     uint32_t imm5;  // encoding for the shift amount
3756     uint32_t carry; // the carry bit after the shift operation
3757     bool setflags;
3758 
3759     // Special case handling!
3760     // A8.6.139 ROR (immediate) -- Encoding T1
3761     ARMEncoding use_encoding = encoding;
3762     if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3763       // Morph the T1 encoding from the ARM Architecture Manual into T2
3764       // encoding to have the same decoding of bit fields as the other Thumb2
3765       // shift operations.
3766       use_encoding = eEncodingT2;
3767     }
3768 
3769     switch (use_encoding) {
3770     case eEncodingT1:
3771       Rd = Bits32(opcode, 2, 0);
3772       Rm = Bits32(opcode, 5, 3);
3773       setflags = !InITBlock();
3774       imm5 = Bits32(opcode, 10, 6);
3775       break;
3776     case eEncodingT2:
3777       // A8.6.141 RRX
3778       // There's no imm form of RRX instructions.
3779       if (shift_type == SRType_RRX)
3780         return false;
3781 
3782       Rd = Bits32(opcode, 11, 8);
3783       Rm = Bits32(opcode, 3, 0);
3784       setflags = BitIsSet(opcode, 20);
3785       imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3786       if (BadReg(Rd) || BadReg(Rm))
3787         return false;
3788       break;
3789     case eEncodingA1:
3790       Rd = Bits32(opcode, 15, 12);
3791       Rm = Bits32(opcode, 3, 0);
3792       setflags = BitIsSet(opcode, 20);
3793       imm5 = Bits32(opcode, 11, 7);
3794       break;
3795     default:
3796       return false;
3797     }
3798 
3799     // A8.6.139 ROR (immediate)
3800     if (shift_type == SRType_ROR && imm5 == 0)
3801       shift_type = SRType_RRX;
3802 
3803     // Get the first operand.
3804     uint32_t value = ReadCoreReg(Rm, &success);
3805     if (!success)
3806       return false;
3807 
3808     // Decode the shift amount if not RRX.
3809     uint32_t amt =
3810         (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3811 
3812     uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3813     if (!success)
3814       return false;
3815 
3816     // The context specifies that an immediate is to be moved into Rd.
3817     EmulateInstruction::Context context;
3818     context.type = EmulateInstruction::eContextImmediate;
3819     context.SetNoArgs();
3820 
3821     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3822       return false;
3823   }
3824   return true;
3825 }
3826 
EmulateShiftReg(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3827 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3828                                             const ARMEncoding encoding,
3829                                             ARM_ShifterType shift_type) {
3830   // assert(shift_type == SRType_ASR
3831   //        || shift_type == SRType_LSL
3832   //        || shift_type == SRType_LSR
3833   //        || shift_type == SRType_ROR);
3834 
3835   bool success = false;
3836 
3837   if (ConditionPassed(opcode)) {
3838     uint32_t Rd; // the destination register
3839     uint32_t Rn; // the first operand register
3840     uint32_t
3841         Rm; // the register whose bottom byte contains the amount to shift by
3842     uint32_t carry; // the carry bit after the shift operation
3843     bool setflags;
3844     switch (encoding) {
3845     case eEncodingT1:
3846       Rd = Bits32(opcode, 2, 0);
3847       Rn = Rd;
3848       Rm = Bits32(opcode, 5, 3);
3849       setflags = !InITBlock();
3850       break;
3851     case eEncodingT2:
3852       Rd = Bits32(opcode, 11, 8);
3853       Rn = Bits32(opcode, 19, 16);
3854       Rm = Bits32(opcode, 3, 0);
3855       setflags = BitIsSet(opcode, 20);
3856       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3857         return false;
3858       break;
3859     case eEncodingA1:
3860       Rd = Bits32(opcode, 15, 12);
3861       Rn = Bits32(opcode, 3, 0);
3862       Rm = Bits32(opcode, 11, 8);
3863       setflags = BitIsSet(opcode, 20);
3864       if (Rd == 15 || Rn == 15 || Rm == 15)
3865         return false;
3866       break;
3867     default:
3868       return false;
3869     }
3870 
3871     // Get the first operand.
3872     uint32_t value = ReadCoreReg(Rn, &success);
3873     if (!success)
3874       return false;
3875     // Get the Rm register content.
3876     uint32_t val = ReadCoreReg(Rm, &success);
3877     if (!success)
3878       return false;
3879 
3880     // Get the shift amount.
3881     uint32_t amt = Bits32(val, 7, 0);
3882 
3883     uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3884     if (!success)
3885       return false;
3886 
3887     // The context specifies that an immediate is to be moved into Rd.
3888     EmulateInstruction::Context context;
3889     context.type = EmulateInstruction::eContextImmediate;
3890     context.SetNoArgs();
3891 
3892     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3893       return false;
3894   }
3895   return true;
3896 }
3897 
3898 // LDM loads multiple registers from consecutive memory locations, using an
3899 // address from a base register.  Optionally the address just above the highest
3900 // of those locations can be written back to the base register.
EmulateLDM(const uint32_t opcode,const ARMEncoding encoding)3901 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3902                                        const ARMEncoding encoding) {
3903 #if 0
3904     // ARM pseudo code...
3905     if ConditionPassed()
3906         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3907         address = R[n];
3908 
3909         for i = 0 to 14
3910             if registers<i> == '1' then
3911                 R[i] = MemA[address, 4]; address = address + 4;
3912         if registers<15> == '1' then
3913             LoadWritePC (MemA[address, 4]);
3914 
3915         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3916         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3917 
3918 #endif
3919 
3920   bool success = false;
3921   if (ConditionPassed(opcode)) {
3922     uint32_t n;
3923     uint32_t registers = 0;
3924     bool wback;
3925     const uint32_t addr_byte_size = GetAddressByteSize();
3926     switch (encoding) {
3927     case eEncodingT1:
3928       // n = UInt(Rn); registers = '00000000':register_list; wback =
3929       // (registers<n> == '0');
3930       n = Bits32(opcode, 10, 8);
3931       registers = Bits32(opcode, 7, 0);
3932       registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3933       wback = BitIsClear(registers, n);
3934       // if BitCount(registers) < 1 then UNPREDICTABLE;
3935       if (BitCount(registers) < 1)
3936         return false;
3937       break;
3938     case eEncodingT2:
3939       // if W == '1' && Rn == '1101' then SEE POP;
3940       // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3941       n = Bits32(opcode, 19, 16);
3942       registers = Bits32(opcode, 15, 0);
3943       registers = registers & 0xdfff; // Make sure bit 13 is zero.
3944       wback = BitIsSet(opcode, 21);
3945 
3946       // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3947       // UNPREDICTABLE;
3948       if ((n == 15) || (BitCount(registers) < 2) ||
3949           (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3950         return false;
3951 
3952       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3953       // UNPREDICTABLE;
3954       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3955         return false;
3956 
3957       // if wback && registers<n> == '1' then UNPREDICTABLE;
3958       if (wback && BitIsSet(registers, n))
3959         return false;
3960       break;
3961 
3962     case eEncodingA1:
3963       n = Bits32(opcode, 19, 16);
3964       registers = Bits32(opcode, 15, 0);
3965       wback = BitIsSet(opcode, 21);
3966       if ((n == 15) || (BitCount(registers) < 1))
3967         return false;
3968       break;
3969     default:
3970       return false;
3971     }
3972 
3973     int32_t offset = 0;
3974     const addr_t base_address =
3975         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3976     if (!success)
3977       return false;
3978 
3979     EmulateInstruction::Context context;
3980     context.type = EmulateInstruction::eContextRegisterPlusOffset;
3981     std::optional<RegisterInfo> dwarf_reg =
3982         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
3983     context.SetRegisterPlusOffset(*dwarf_reg, offset);
3984 
3985     for (int i = 0; i < 14; ++i) {
3986       if (BitIsSet(registers, i)) {
3987         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3988         context.SetRegisterPlusOffset(*dwarf_reg, offset);
3989         if (wback && (n == 13)) // Pop Instruction
3990         {
3991           context.type = EmulateInstruction::eContextPopRegisterOffStack;
3992           context.SetAddress(base_address + offset);
3993         }
3994 
3995         // R[i] = MemA [address, 4]; address = address + 4;
3996         uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
3997                                  0, &success);
3998         if (!success)
3999           return false;
4000 
4001         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4002                                    data))
4003           return false;
4004 
4005         offset += addr_byte_size;
4006       }
4007     }
4008 
4009     if (BitIsSet(registers, 15)) {
4010       // LoadWritePC (MemA [address, 4]);
4011       context.type = EmulateInstruction::eContextRegisterPlusOffset;
4012       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4013       uint32_t data =
4014           MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4015       if (!success)
4016         return false;
4017       // In ARMv5T and above, this is an interworking branch.
4018       if (!LoadWritePC(context, data))
4019         return false;
4020     }
4021 
4022     if (wback && BitIsClear(registers, n)) {
4023       // R[n] = R[n] + 4 * BitCount (registers)
4024       int32_t offset = addr_byte_size * BitCount(registers);
4025       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4026       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4027 
4028       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4029                                  base_address + offset))
4030         return false;
4031     }
4032     if (wback && BitIsSet(registers, n))
4033       // R[n] bits(32) UNKNOWN;
4034       return WriteBits32Unknown(n);
4035   }
4036   return true;
4037 }
4038 
4039 // LDMDA loads multiple registers from consecutive memory locations using an
4040 // address from a base register.
4041 // The consecutive memory locations end at this address and the address just
4042 // below the lowest of those locations can optionally be written back to the
4043 // base register.
EmulateLDMDA(const uint32_t opcode,const ARMEncoding encoding)4044 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4045                                          const ARMEncoding encoding) {
4046 #if 0
4047     // ARM pseudo code...
4048     if ConditionPassed() then
4049         EncodingSpecificOperations();
4050         address = R[n] - 4*BitCount(registers) + 4;
4051 
4052         for i = 0 to 14
4053             if registers<i> == '1' then
4054                   R[i] = MemA[address,4]; address = address + 4;
4055 
4056         if registers<15> == '1' then
4057             LoadWritePC(MemA[address,4]);
4058 
4059         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4060         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4061 #endif
4062 
4063   bool success = false;
4064 
4065   if (ConditionPassed(opcode)) {
4066     uint32_t n;
4067     uint32_t registers = 0;
4068     bool wback;
4069     const uint32_t addr_byte_size = GetAddressByteSize();
4070 
4071     // EncodingSpecificOperations();
4072     switch (encoding) {
4073     case eEncodingA1:
4074       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4075       n = Bits32(opcode, 19, 16);
4076       registers = Bits32(opcode, 15, 0);
4077       wback = BitIsSet(opcode, 21);
4078 
4079       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4080       if ((n == 15) || (BitCount(registers) < 1))
4081         return false;
4082 
4083       break;
4084 
4085     default:
4086       return false;
4087     }
4088     // address = R[n] - 4*BitCount(registers) + 4;
4089 
4090     int32_t offset = 0;
4091     addr_t Rn = ReadCoreReg(n, &success);
4092 
4093     if (!success)
4094       return false;
4095 
4096     addr_t address =
4097         Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4098 
4099     EmulateInstruction::Context context;
4100     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4101     std::optional<RegisterInfo> dwarf_reg =
4102         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4103     context.SetRegisterPlusOffset(*dwarf_reg, offset);
4104 
4105     // for i = 0 to 14
4106     for (int i = 0; i < 14; ++i) {
4107       // if registers<i> == '1' then
4108       if (BitIsSet(registers, i)) {
4109         // R[i] = MemA[address,4]; address = address + 4;
4110         context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4111         uint32_t data =
4112             MemARead(context, address + offset, addr_byte_size, 0, &success);
4113         if (!success)
4114           return false;
4115         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4116                                    data))
4117           return false;
4118         offset += addr_byte_size;
4119       }
4120     }
4121 
4122     // if registers<15> == '1' then
4123     //     LoadWritePC(MemA[address,4]);
4124     if (BitIsSet(registers, 15)) {
4125       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4126       uint32_t data =
4127           MemARead(context, address + offset, addr_byte_size, 0, &success);
4128       if (!success)
4129         return false;
4130       // In ARMv5T and above, this is an interworking branch.
4131       if (!LoadWritePC(context, data))
4132         return false;
4133     }
4134 
4135     // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4136     if (wback && BitIsClear(registers, n)) {
4137 
4138       offset = (addr_byte_size * BitCount(registers)) * -1;
4139       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4140       context.SetImmediateSigned(offset);
4141       addr_t addr = Rn + offset;
4142       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4143                                  addr))
4144         return false;
4145     }
4146 
4147     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4148     if (wback && BitIsSet(registers, n))
4149       return WriteBits32Unknown(n);
4150   }
4151   return true;
4152 }
4153 
4154 // LDMDB loads multiple registers from consecutive memory locations using an
4155 // address from a base register.  The
4156 // consecutive memory locations end just below this address, and the address of
4157 // the lowest of those locations can be optionally written back to the base
4158 // register.
EmulateLDMDB(const uint32_t opcode,const ARMEncoding encoding)4159 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4160                                          const ARMEncoding encoding) {
4161 #if 0
4162     // ARM pseudo code...
4163     if ConditionPassed() then
4164         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4165         address = R[n] - 4*BitCount(registers);
4166 
4167         for i = 0 to 14
4168             if registers<i> == '1' then
4169                   R[i] = MemA[address,4]; address = address + 4;
4170         if registers<15> == '1' then
4171                   LoadWritePC(MemA[address,4]);
4172 
4173         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4174         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4175 #endif
4176 
4177   bool success = false;
4178 
4179   if (ConditionPassed(opcode)) {
4180     uint32_t n;
4181     uint32_t registers = 0;
4182     bool wback;
4183     const uint32_t addr_byte_size = GetAddressByteSize();
4184     switch (encoding) {
4185     case eEncodingT1:
4186       // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4187       n = Bits32(opcode, 19, 16);
4188       registers = Bits32(opcode, 15, 0);
4189       registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4190       wback = BitIsSet(opcode, 21);
4191 
4192       // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4193       // UNPREDICTABLE;
4194       if ((n == 15) || (BitCount(registers) < 2) ||
4195           (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4196         return false;
4197 
4198       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4199       // UNPREDICTABLE;
4200       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4201         return false;
4202 
4203       // if wback && registers<n> == '1' then UNPREDICTABLE;
4204       if (wback && BitIsSet(registers, n))
4205         return false;
4206 
4207       break;
4208 
4209     case eEncodingA1:
4210       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4211       n = Bits32(opcode, 19, 16);
4212       registers = Bits32(opcode, 15, 0);
4213       wback = BitIsSet(opcode, 21);
4214 
4215       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4216       if ((n == 15) || (BitCount(registers) < 1))
4217         return false;
4218 
4219       break;
4220 
4221     default:
4222       return false;
4223     }
4224 
4225     // address = R[n] - 4*BitCount(registers);
4226 
4227     int32_t offset = 0;
4228     addr_t Rn =
4229         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4230 
4231     if (!success)
4232       return false;
4233 
4234     addr_t address = Rn - (addr_byte_size * BitCount(registers));
4235     EmulateInstruction::Context context;
4236     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4237     std::optional<RegisterInfo> dwarf_reg =
4238         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4239     context.SetRegisterPlusOffset(*dwarf_reg, Rn - address);
4240 
4241     for (int i = 0; i < 14; ++i) {
4242       if (BitIsSet(registers, i)) {
4243         // R[i] = MemA[address,4]; address = address + 4;
4244         context.SetRegisterPlusOffset(*dwarf_reg, Rn - (address + offset));
4245         uint32_t data =
4246             MemARead(context, address + offset, addr_byte_size, 0, &success);
4247         if (!success)
4248           return false;
4249 
4250         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4251                                    data))
4252           return false;
4253 
4254         offset += addr_byte_size;
4255       }
4256     }
4257 
4258     // if registers<15> == '1' then
4259     //     LoadWritePC(MemA[address,4]);
4260     if (BitIsSet(registers, 15)) {
4261       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4262       uint32_t data =
4263           MemARead(context, address + offset, addr_byte_size, 0, &success);
4264       if (!success)
4265         return false;
4266       // In ARMv5T and above, this is an interworking branch.
4267       if (!LoadWritePC(context, data))
4268         return false;
4269     }
4270 
4271     // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4272     if (wback && BitIsClear(registers, n)) {
4273 
4274       offset = (addr_byte_size * BitCount(registers)) * -1;
4275       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4276       context.SetImmediateSigned(offset);
4277       addr_t addr = Rn + offset;
4278       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4279                                  addr))
4280         return false;
4281     }
4282 
4283     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4284     // possible for encoding A1
4285     if (wback && BitIsSet(registers, n))
4286       return WriteBits32Unknown(n);
4287   }
4288   return true;
4289 }
4290 
4291 // LDMIB loads multiple registers from consecutive memory locations using an
4292 // address from a base register.  The
4293 // consecutive memory locations start just above this address, and thea ddress
4294 // of the last of those locations can optinoally be written back to the base
4295 // register.
EmulateLDMIB(const uint32_t opcode,const ARMEncoding encoding)4296 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4297                                          const ARMEncoding encoding) {
4298 #if 0
4299     if ConditionPassed() then
4300         EncodingSpecificOperations();
4301         address = R[n] + 4;
4302 
4303         for i = 0 to 14
4304             if registers<i> == '1' then
4305                   R[i] = MemA[address,4]; address = address + 4;
4306         if registers<15> == '1' then
4307             LoadWritePC(MemA[address,4]);
4308 
4309         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4310         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4311 #endif
4312 
4313   bool success = false;
4314 
4315   if (ConditionPassed(opcode)) {
4316     uint32_t n;
4317     uint32_t registers = 0;
4318     bool wback;
4319     const uint32_t addr_byte_size = GetAddressByteSize();
4320     switch (encoding) {
4321     case eEncodingA1:
4322       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4323       n = Bits32(opcode, 19, 16);
4324       registers = Bits32(opcode, 15, 0);
4325       wback = BitIsSet(opcode, 21);
4326 
4327       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4328       if ((n == 15) || (BitCount(registers) < 1))
4329         return false;
4330 
4331       break;
4332     default:
4333       return false;
4334     }
4335     // address = R[n] + 4;
4336 
4337     int32_t offset = 0;
4338     addr_t Rn =
4339         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4340 
4341     if (!success)
4342       return false;
4343 
4344     addr_t address = Rn + addr_byte_size;
4345 
4346     EmulateInstruction::Context context;
4347     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4348     std::optional<RegisterInfo> dwarf_reg =
4349         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4350     context.SetRegisterPlusOffset(*dwarf_reg, offset);
4351 
4352     for (int i = 0; i < 14; ++i) {
4353       if (BitIsSet(registers, i)) {
4354         // R[i] = MemA[address,4]; address = address + 4;
4355 
4356         context.SetRegisterPlusOffset(*dwarf_reg, offset + addr_byte_size);
4357         uint32_t data =
4358             MemARead(context, address + offset, addr_byte_size, 0, &success);
4359         if (!success)
4360           return false;
4361 
4362         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4363                                    data))
4364           return false;
4365 
4366         offset += addr_byte_size;
4367       }
4368     }
4369 
4370     // if registers<15> == '1' then
4371     //     LoadWritePC(MemA[address,4]);
4372     if (BitIsSet(registers, 15)) {
4373       context.SetRegisterPlusOffset(*dwarf_reg, offset);
4374       uint32_t data =
4375           MemARead(context, address + offset, addr_byte_size, 0, &success);
4376       if (!success)
4377         return false;
4378       // In ARMv5T and above, this is an interworking branch.
4379       if (!LoadWritePC(context, data))
4380         return false;
4381     }
4382 
4383     // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4384     if (wback && BitIsClear(registers, n)) {
4385 
4386       offset = addr_byte_size * BitCount(registers);
4387       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4388       context.SetImmediateSigned(offset);
4389       addr_t addr = Rn + offset;
4390       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4391                                  addr))
4392         return false;
4393     }
4394 
4395     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4396     // possible for encoding A1
4397     if (wback && BitIsSet(registers, n))
4398       return WriteBits32Unknown(n);
4399   }
4400   return true;
4401 }
4402 
4403 // Load Register (immediate) calculates an address from a base register value
4404 // and an immediate offset, loads a word from memory, and writes to a register.
4405 // LDR (immediate, Thumb)
EmulateLDRRtRnImm(const uint32_t opcode,const ARMEncoding encoding)4406 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4407                                               const ARMEncoding encoding) {
4408 #if 0
4409     // ARM pseudo code...
4410     if (ConditionPassed())
4411     {
4412         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4413         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4414         address = if index then offset_addr else R[n];
4415         data = MemU[address,4];
4416         if wback then R[n] = offset_addr;
4417         if t == 15 then
4418             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4419         elsif UnalignedSupport() || address<1:0> = '00' then
4420             R[t] = data;
4421         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4422     }
4423 #endif
4424 
4425   bool success = false;
4426 
4427   if (ConditionPassed(opcode)) {
4428     uint32_t Rt;        // the destination register
4429     uint32_t Rn;        // the base register
4430     uint32_t imm32;     // the immediate offset used to form the address
4431     addr_t offset_addr; // the offset address
4432     addr_t address;     // the calculated address
4433     uint32_t data;      // the literal data value from memory load
4434     bool add, index, wback;
4435     switch (encoding) {
4436     case eEncodingT1:
4437       Rt = Bits32(opcode, 2, 0);
4438       Rn = Bits32(opcode, 5, 3);
4439       imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4440       // index = TRUE; add = TRUE; wback = FALSE
4441       add = true;
4442       index = true;
4443       wback = false;
4444 
4445       break;
4446 
4447     case eEncodingT2:
4448       // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4449       Rt = Bits32(opcode, 10, 8);
4450       Rn = 13;
4451       imm32 = Bits32(opcode, 7, 0) << 2;
4452 
4453       // index = TRUE; add = TRUE; wback = FALSE;
4454       index = true;
4455       add = true;
4456       wback = false;
4457 
4458       break;
4459 
4460     case eEncodingT3:
4461       // if Rn == '1111' then SEE LDR (literal);
4462       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4463       Rt = Bits32(opcode, 15, 12);
4464       Rn = Bits32(opcode, 19, 16);
4465       imm32 = Bits32(opcode, 11, 0);
4466 
4467       // index = TRUE; add = TRUE; wback = FALSE;
4468       index = true;
4469       add = true;
4470       wback = false;
4471 
4472       // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4473       if ((Rt == 15) && InITBlock() && !LastInITBlock())
4474         return false;
4475 
4476       break;
4477 
4478     case eEncodingT4:
4479       // if Rn == '1111' then SEE LDR (literal);
4480       // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4481       // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4482       // '00000100' then SEE POP;
4483       // if P == '0' && W == '0' then UNDEFINED;
4484       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4485         return false;
4486 
4487       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4488       Rt = Bits32(opcode, 15, 12);
4489       Rn = Bits32(opcode, 19, 16);
4490       imm32 = Bits32(opcode, 7, 0);
4491 
4492       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4493       index = BitIsSet(opcode, 10);
4494       add = BitIsSet(opcode, 9);
4495       wback = BitIsSet(opcode, 8);
4496 
4497       // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4498       // then UNPREDICTABLE;
4499       if ((wback && (Rn == Rt)) ||
4500           ((Rt == 15) && InITBlock() && !LastInITBlock()))
4501         return false;
4502 
4503       break;
4504 
4505     default:
4506       return false;
4507     }
4508     uint32_t base = ReadCoreReg(Rn, &success);
4509     if (!success)
4510       return false;
4511     if (add)
4512       offset_addr = base + imm32;
4513     else
4514       offset_addr = base - imm32;
4515 
4516     address = (index ? offset_addr : base);
4517 
4518     std::optional<RegisterInfo> base_reg =
4519         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn);
4520     if (wback) {
4521       EmulateInstruction::Context ctx;
4522       if (Rn == 13) {
4523         ctx.type = eContextAdjustStackPointer;
4524         ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4525       } else if (Rn == GetFramePointerRegisterNumber()) {
4526         ctx.type = eContextSetFramePointer;
4527         ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4528       } else {
4529         ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4530         ctx.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4531       }
4532 
4533       if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4534                                  offset_addr))
4535         return false;
4536     }
4537 
4538     // Prepare to write to the Rt register.
4539     EmulateInstruction::Context context;
4540     context.type = EmulateInstruction::eContextRegisterLoad;
4541     context.SetRegisterPlusOffset(*base_reg, (int32_t)(offset_addr - base));
4542 
4543     // Read memory from the address.
4544     data = MemURead(context, address, 4, 0, &success);
4545     if (!success)
4546       return false;
4547 
4548     if (Rt == 15) {
4549       if (Bits32(address, 1, 0) == 0) {
4550         if (!LoadWritePC(context, data))
4551           return false;
4552       } else
4553         return false;
4554     } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4555       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4556                                  data))
4557         return false;
4558     } else
4559       WriteBits32Unknown(Rt);
4560   }
4561   return true;
4562 }
4563 
4564 // STM (Store Multiple Increment After) stores multiple registers to consecutive
4565 // memory locations using an address
4566 // from a base register.  The consecutive memory locations start at this
4567 // address, and the address just above the last of those locations can
4568 // optionally be written back to the base register.
EmulateSTM(const uint32_t opcode,const ARMEncoding encoding)4569 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4570                                        const ARMEncoding encoding) {
4571 #if 0
4572     if ConditionPassed() then
4573         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4574         address = R[n];
4575 
4576         for i = 0 to 14
4577             if registers<i> == '1' then
4578                 if i == n && wback && i != LowestSetBit(registers) then
4579                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4580                 else
4581                     MemA[address,4] = R[i];
4582                 address = address + 4;
4583 
4584         if registers<15> == '1' then // Only possible for encoding A1
4585             MemA[address,4] = PCStoreValue();
4586         if wback then R[n] = R[n] + 4*BitCount(registers);
4587 #endif
4588 
4589   bool success = false;
4590 
4591   if (ConditionPassed(opcode)) {
4592     uint32_t n;
4593     uint32_t registers = 0;
4594     bool wback;
4595     const uint32_t addr_byte_size = GetAddressByteSize();
4596 
4597     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4598     switch (encoding) {
4599     case eEncodingT1:
4600       // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4601       n = Bits32(opcode, 10, 8);
4602       registers = Bits32(opcode, 7, 0);
4603       registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4604       wback = true;
4605 
4606       // if BitCount(registers) < 1 then UNPREDICTABLE;
4607       if (BitCount(registers) < 1)
4608         return false;
4609 
4610       break;
4611 
4612     case eEncodingT2:
4613       // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4614       n = Bits32(opcode, 19, 16);
4615       registers = Bits32(opcode, 15, 0);
4616       registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4617       wback = BitIsSet(opcode, 21);
4618 
4619       // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4620       if ((n == 15) || (BitCount(registers) < 2))
4621         return false;
4622 
4623       // if wback && registers<n> == '1' then UNPREDICTABLE;
4624       if (wback && BitIsSet(registers, n))
4625         return false;
4626 
4627       break;
4628 
4629     case eEncodingA1:
4630       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4631       n = Bits32(opcode, 19, 16);
4632       registers = Bits32(opcode, 15, 0);
4633       wback = BitIsSet(opcode, 21);
4634 
4635       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4636       if ((n == 15) || (BitCount(registers) < 1))
4637         return false;
4638 
4639       break;
4640 
4641     default:
4642       return false;
4643     }
4644 
4645     // address = R[n];
4646     int32_t offset = 0;
4647     const addr_t address =
4648         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4649     if (!success)
4650       return false;
4651 
4652     EmulateInstruction::Context context;
4653     context.type = EmulateInstruction::eContextRegisterStore;
4654     std::optional<RegisterInfo> base_reg =
4655         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4656 
4657     // for i = 0 to 14
4658     uint32_t lowest_set_bit = 14;
4659     for (uint32_t i = 0; i < 14; ++i) {
4660       // if registers<i> == '1' then
4661       if (BitIsSet(registers, i)) {
4662         if (i < lowest_set_bit)
4663           lowest_set_bit = i;
4664         // if i == n && wback && i != LowestSetBit(registers) then
4665         if ((i == n) && wback && (i != lowest_set_bit))
4666           // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4667           // T1 and A1
4668           WriteBits32UnknownToMemory(address + offset);
4669         else {
4670           // MemA[address,4] = R[i];
4671           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4672                                                0, &success);
4673           if (!success)
4674             return false;
4675 
4676           std::optional<RegisterInfo> data_reg =
4677               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4678           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
4679           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4680             return false;
4681         }
4682 
4683         // address = address + 4;
4684         offset += addr_byte_size;
4685       }
4686     }
4687 
4688     // if registers<15> == '1' then // Only possible for encoding A1
4689     //     MemA[address,4] = PCStoreValue();
4690     if (BitIsSet(registers, 15)) {
4691       std::optional<RegisterInfo> pc_reg =
4692           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4693       context.SetRegisterPlusOffset(*pc_reg, 8);
4694       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4695       if (!success)
4696         return false;
4697 
4698       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4699         return false;
4700     }
4701 
4702     // if wback then R[n] = R[n] + 4*BitCount(registers);
4703     if (wback) {
4704       offset = addr_byte_size * BitCount(registers);
4705       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4706       context.SetImmediateSigned(offset);
4707       addr_t data = address + offset;
4708       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4709                                  data))
4710         return false;
4711     }
4712   }
4713   return true;
4714 }
4715 
4716 // STMDA (Store Multiple Decrement After) stores multiple registers to
4717 // consecutive memory locations using an address from a base register.  The
4718 // consecutive memory locations end at this address, and the address just below
4719 // the lowest of those locations can optionally be written back to the base
4720 // register.
EmulateSTMDA(const uint32_t opcode,const ARMEncoding encoding)4721 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4722                                          const ARMEncoding encoding) {
4723 #if 0
4724     if ConditionPassed() then
4725         EncodingSpecificOperations();
4726         address = R[n] - 4*BitCount(registers) + 4;
4727 
4728         for i = 0 to 14
4729             if registers<i> == '1' then
4730                 if i == n && wback && i != LowestSetBit(registers) then
4731                     MemA[address,4] = bits(32) UNKNOWN;
4732                 else
4733                     MemA[address,4] = R[i];
4734                 address = address + 4;
4735 
4736         if registers<15> == '1' then
4737             MemA[address,4] = PCStoreValue();
4738 
4739         if wback then R[n] = R[n] - 4*BitCount(registers);
4740 #endif
4741 
4742   bool success = false;
4743 
4744   if (ConditionPassed(opcode)) {
4745     uint32_t n;
4746     uint32_t registers = 0;
4747     bool wback;
4748     const uint32_t addr_byte_size = GetAddressByteSize();
4749 
4750     // EncodingSpecificOperations();
4751     switch (encoding) {
4752     case eEncodingA1:
4753       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4754       n = Bits32(opcode, 19, 16);
4755       registers = Bits32(opcode, 15, 0);
4756       wback = BitIsSet(opcode, 21);
4757 
4758       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4759       if ((n == 15) || (BitCount(registers) < 1))
4760         return false;
4761       break;
4762     default:
4763       return false;
4764     }
4765 
4766     // address = R[n] - 4*BitCount(registers) + 4;
4767     int32_t offset = 0;
4768     addr_t Rn = ReadCoreReg(n, &success);
4769     if (!success)
4770       return false;
4771 
4772     addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4773 
4774     EmulateInstruction::Context context;
4775     context.type = EmulateInstruction::eContextRegisterStore;
4776     std::optional<RegisterInfo> base_reg =
4777         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4778 
4779     // for i = 0 to 14
4780     uint32_t lowest_bit_set = 14;
4781     for (uint32_t i = 0; i < 14; ++i) {
4782       // if registers<i> == '1' then
4783       if (BitIsSet(registers, i)) {
4784         if (i < lowest_bit_set)
4785           lowest_bit_set = i;
4786         // if i == n && wback && i != LowestSetBit(registers) then
4787         if ((i == n) && wback && (i != lowest_bit_set))
4788           // MemA[address,4] = bits(32) UNKNOWN;
4789           WriteBits32UnknownToMemory(address + offset);
4790         else {
4791           // MemA[address,4] = R[i];
4792           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4793                                                0, &success);
4794           if (!success)
4795             return false;
4796 
4797           std::optional<RegisterInfo> data_reg =
4798               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4799           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4800                                                   Rn - (address + offset));
4801           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4802             return false;
4803         }
4804 
4805         // address = address + 4;
4806         offset += addr_byte_size;
4807       }
4808     }
4809 
4810     // if registers<15> == '1' then
4811     //    MemA[address,4] = PCStoreValue();
4812     if (BitIsSet(registers, 15)) {
4813       std::optional<RegisterInfo> pc_reg =
4814           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4815       context.SetRegisterPlusOffset(*pc_reg, 8);
4816       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4817       if (!success)
4818         return false;
4819 
4820       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4821         return false;
4822     }
4823 
4824     // if wback then R[n] = R[n] - 4*BitCount(registers);
4825     if (wback) {
4826       offset = (addr_byte_size * BitCount(registers)) * -1;
4827       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4828       context.SetImmediateSigned(offset);
4829       addr_t data = Rn + offset;
4830       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4831                                  data))
4832         return false;
4833     }
4834   }
4835   return true;
4836 }
4837 
4838 // STMDB (Store Multiple Decrement Before) stores multiple registers to
4839 // consecutive memory locations using an address from a base register.  The
4840 // consecutive memory locations end just below this address, and the address of
4841 // the first of those locations can optionally be written back to the base
4842 // register.
EmulateSTMDB(const uint32_t opcode,const ARMEncoding encoding)4843 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4844                                          const ARMEncoding encoding) {
4845 #if 0
4846     if ConditionPassed() then
4847         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4848         address = R[n] - 4*BitCount(registers);
4849 
4850         for i = 0 to 14
4851             if registers<i> == '1' then
4852                 if i == n && wback && i != LowestSetBit(registers) then
4853                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4854                 else
4855                     MemA[address,4] = R[i];
4856                 address = address + 4;
4857 
4858         if registers<15> == '1' then // Only possible for encoding A1
4859             MemA[address,4] = PCStoreValue();
4860 
4861         if wback then R[n] = R[n] - 4*BitCount(registers);
4862 #endif
4863 
4864   bool success = false;
4865 
4866   if (ConditionPassed(opcode)) {
4867     uint32_t n;
4868     uint32_t registers = 0;
4869     bool wback;
4870     const uint32_t addr_byte_size = GetAddressByteSize();
4871 
4872     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4873     switch (encoding) {
4874     case eEncodingT1:
4875       // if W == '1' && Rn == '1101' then SEE PUSH;
4876       if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4877         // See PUSH
4878       }
4879       // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4880       n = Bits32(opcode, 19, 16);
4881       registers = Bits32(opcode, 15, 0);
4882       registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4883       wback = BitIsSet(opcode, 21);
4884       // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4885       if ((n == 15) || BitCount(registers) < 2)
4886         return false;
4887       // if wback && registers<n> == '1' then UNPREDICTABLE;
4888       if (wback && BitIsSet(registers, n))
4889         return false;
4890       break;
4891 
4892     case eEncodingA1:
4893       // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4894       // PUSH;
4895       if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4896           BitCount(Bits32(opcode, 15, 0)) >= 2) {
4897         // See Push
4898       }
4899       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4900       n = Bits32(opcode, 19, 16);
4901       registers = Bits32(opcode, 15, 0);
4902       wback = BitIsSet(opcode, 21);
4903       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4904       if ((n == 15) || BitCount(registers) < 1)
4905         return false;
4906       break;
4907 
4908     default:
4909       return false;
4910     }
4911 
4912     // address = R[n] - 4*BitCount(registers);
4913 
4914     int32_t offset = 0;
4915     addr_t Rn =
4916         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4917     if (!success)
4918       return false;
4919 
4920     addr_t address = Rn - (addr_byte_size * BitCount(registers));
4921 
4922     EmulateInstruction::Context context;
4923     context.type = EmulateInstruction::eContextRegisterStore;
4924     std::optional<RegisterInfo> base_reg =
4925         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
4926 
4927     // for i = 0 to 14
4928     uint32_t lowest_set_bit = 14;
4929     for (uint32_t i = 0; i < 14; ++i) {
4930       // if registers<i> == '1' then
4931       if (BitIsSet(registers, i)) {
4932         if (i < lowest_set_bit)
4933           lowest_set_bit = i;
4934         // if i == n && wback && i != LowestSetBit(registers) then
4935         if ((i == n) && wback && (i != lowest_set_bit))
4936           // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4937           // A1
4938           WriteBits32UnknownToMemory(address + offset);
4939         else {
4940           // MemA[address,4] = R[i];
4941           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4942                                                0, &success);
4943           if (!success)
4944             return false;
4945 
4946           std::optional<RegisterInfo> data_reg =
4947               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
4948           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
4949                                                   Rn - (address + offset));
4950           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4951             return false;
4952         }
4953 
4954         // address = address + 4;
4955         offset += addr_byte_size;
4956       }
4957     }
4958 
4959     // if registers<15> == '1' then // Only possible for encoding A1
4960     //     MemA[address,4] = PCStoreValue();
4961     if (BitIsSet(registers, 15)) {
4962       std::optional<RegisterInfo> pc_reg =
4963           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
4964       context.SetRegisterPlusOffset(*pc_reg, 8);
4965       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4966       if (!success)
4967         return false;
4968 
4969       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4970         return false;
4971     }
4972 
4973     // if wback then R[n] = R[n] - 4*BitCount(registers);
4974     if (wback) {
4975       offset = (addr_byte_size * BitCount(registers)) * -1;
4976       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4977       context.SetImmediateSigned(offset);
4978       addr_t data = Rn + offset;
4979       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4980                                  data))
4981         return false;
4982     }
4983   }
4984   return true;
4985 }
4986 
4987 // STMIB (Store Multiple Increment Before) stores multiple registers to
4988 // consecutive memory locations using an address from a base register.  The
4989 // consecutive memory locations start just above this address, and the address
4990 // of the last of those locations can optionally be written back to the base
4991 // register.
EmulateSTMIB(const uint32_t opcode,const ARMEncoding encoding)4992 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
4993                                          const ARMEncoding encoding) {
4994 #if 0
4995     if ConditionPassed() then
4996         EncodingSpecificOperations();
4997         address = R[n] + 4;
4998 
4999         for i = 0 to 14
5000             if registers<i> == '1' then
5001                 if i == n && wback && i != LowestSetBit(registers) then
5002                     MemA[address,4] = bits(32) UNKNOWN;
5003                 else
5004                     MemA[address,4] = R[i];
5005                 address = address + 4;
5006 
5007         if registers<15> == '1' then
5008             MemA[address,4] = PCStoreValue();
5009 
5010         if wback then R[n] = R[n] + 4*BitCount(registers);
5011 #endif
5012 
5013   bool success = false;
5014 
5015   if (ConditionPassed(opcode)) {
5016     uint32_t n;
5017     uint32_t registers = 0;
5018     bool wback;
5019     const uint32_t addr_byte_size = GetAddressByteSize();
5020 
5021     // EncodingSpecificOperations();
5022     switch (encoding) {
5023     case eEncodingA1:
5024       // n = UInt(Rn); registers = register_list; wback = (W == '1');
5025       n = Bits32(opcode, 19, 16);
5026       registers = Bits32(opcode, 15, 0);
5027       wback = BitIsSet(opcode, 21);
5028 
5029       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5030       if ((n == 15) && (BitCount(registers) < 1))
5031         return false;
5032       break;
5033     default:
5034       return false;
5035     }
5036     // address = R[n] + 4;
5037 
5038     int32_t offset = 0;
5039     addr_t Rn = ReadCoreReg(n, &success);
5040     if (!success)
5041       return false;
5042 
5043     addr_t address = Rn + addr_byte_size;
5044 
5045     EmulateInstruction::Context context;
5046     context.type = EmulateInstruction::eContextRegisterStore;
5047     std::optional<RegisterInfo> base_reg =
5048         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5049 
5050     uint32_t lowest_set_bit = 14;
5051     // for i = 0 to 14
5052     for (uint32_t i = 0; i < 14; ++i) {
5053       // if registers<i> == '1' then
5054       if (BitIsSet(registers, i)) {
5055         if (i < lowest_set_bit)
5056           lowest_set_bit = i;
5057         // if i == n && wback && i != LowestSetBit(registers) then
5058         if ((i == n) && wback && (i != lowest_set_bit))
5059           // MemA[address,4] = bits(32) UNKNOWN;
5060           WriteBits32UnknownToMemory(address + offset);
5061         // else
5062         else {
5063           // MemA[address,4] = R[i];
5064           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5065                                                0, &success);
5066           if (!success)
5067             return false;
5068 
5069           std::optional<RegisterInfo> data_reg =
5070               GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i);
5071           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5072                                                   offset + addr_byte_size);
5073           if (!MemAWrite(context, address + offset, data, addr_byte_size))
5074             return false;
5075         }
5076 
5077         // address = address + 4;
5078         offset += addr_byte_size;
5079       }
5080     }
5081 
5082     // if registers<15> == '1' then
5083     // MemA[address,4] = PCStoreValue();
5084     if (BitIsSet(registers, 15)) {
5085       std::optional<RegisterInfo> pc_reg =
5086           GetRegisterInfo(eRegisterKindDWARF, dwarf_pc);
5087       context.SetRegisterPlusOffset(*pc_reg, 8);
5088       const uint32_t pc = ReadCoreReg(PC_REG, &success);
5089       if (!success)
5090         return false;
5091 
5092       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5093         return false;
5094     }
5095 
5096     // if wback then R[n] = R[n] + 4*BitCount(registers);
5097     if (wback) {
5098       offset = addr_byte_size * BitCount(registers);
5099       context.type = EmulateInstruction::eContextAdjustBaseRegister;
5100       context.SetImmediateSigned(offset);
5101       addr_t data = Rn + offset;
5102       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5103                                  data))
5104         return false;
5105     }
5106   }
5107   return true;
5108 }
5109 
5110 // STR (store immediate) calculates an address from a base register value and an
5111 // immediate offset, and stores a word
5112 // from a register to memory.  It can use offset, post-indexed, or pre-indexed
5113 // addressing.
EmulateSTRThumb(const uint32_t opcode,const ARMEncoding encoding)5114 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5115                                             const ARMEncoding encoding) {
5116 #if 0
5117     if ConditionPassed() then
5118         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5119         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5120         address = if index then offset_addr else R[n];
5121         if UnalignedSupport() || address<1:0> == '00' then
5122             MemU[address,4] = R[t];
5123         else // Can only occur before ARMv7
5124             MemU[address,4] = bits(32) UNKNOWN;
5125         if wback then R[n] = offset_addr;
5126 #endif
5127 
5128   bool success = false;
5129 
5130   if (ConditionPassed(opcode)) {
5131     const uint32_t addr_byte_size = GetAddressByteSize();
5132 
5133     uint32_t t;
5134     uint32_t n;
5135     uint32_t imm32;
5136     bool index;
5137     bool add;
5138     bool wback;
5139     // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5140     switch (encoding) {
5141     case eEncodingT1:
5142       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5143       t = Bits32(opcode, 2, 0);
5144       n = Bits32(opcode, 5, 3);
5145       imm32 = Bits32(opcode, 10, 6) << 2;
5146 
5147       // index = TRUE; add = TRUE; wback = FALSE;
5148       index = true;
5149       add = false;
5150       wback = false;
5151       break;
5152 
5153     case eEncodingT2:
5154       // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5155       t = Bits32(opcode, 10, 8);
5156       n = 13;
5157       imm32 = Bits32(opcode, 7, 0) << 2;
5158 
5159       // index = TRUE; add = TRUE; wback = FALSE;
5160       index = true;
5161       add = true;
5162       wback = false;
5163       break;
5164 
5165     case eEncodingT3:
5166       // if Rn == '1111' then UNDEFINED;
5167       if (Bits32(opcode, 19, 16) == 15)
5168         return false;
5169 
5170       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5171       t = Bits32(opcode, 15, 12);
5172       n = Bits32(opcode, 19, 16);
5173       imm32 = Bits32(opcode, 11, 0);
5174 
5175       // index = TRUE; add = TRUE; wback = FALSE;
5176       index = true;
5177       add = true;
5178       wback = false;
5179 
5180       // if t == 15 then UNPREDICTABLE;
5181       if (t == 15)
5182         return false;
5183       break;
5184 
5185     case eEncodingT4:
5186       // if P == '1' && U == '1' && W == '0' then SEE STRT;
5187       // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5188       // '00000100' then SEE PUSH;
5189       // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5190       if ((Bits32(opcode, 19, 16) == 15) ||
5191           (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5192         return false;
5193 
5194       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5195       t = Bits32(opcode, 15, 12);
5196       n = Bits32(opcode, 19, 16);
5197       imm32 = Bits32(opcode, 7, 0);
5198 
5199       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5200       index = BitIsSet(opcode, 10);
5201       add = BitIsSet(opcode, 9);
5202       wback = BitIsSet(opcode, 8);
5203 
5204       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5205       if ((t == 15) || (wback && (n == t)))
5206         return false;
5207       break;
5208 
5209     default:
5210       return false;
5211     }
5212 
5213     addr_t offset_addr;
5214     addr_t address;
5215 
5216     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5217     uint32_t base_address = ReadCoreReg(n, &success);
5218     if (!success)
5219       return false;
5220 
5221     if (add)
5222       offset_addr = base_address + imm32;
5223     else
5224       offset_addr = base_address - imm32;
5225 
5226     // address = if index then offset_addr else R[n];
5227     if (index)
5228       address = offset_addr;
5229     else
5230       address = base_address;
5231 
5232     EmulateInstruction::Context context;
5233     if (n == 13)
5234       context.type = eContextPushRegisterOnStack;
5235     else
5236       context.type = eContextRegisterStore;
5237 
5238     std::optional<RegisterInfo> base_reg =
5239         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5240 
5241     // if UnalignedSupport() || address<1:0> == '00' then
5242     if (UnalignedSupport() ||
5243         (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5244       // MemU[address,4] = R[t];
5245       uint32_t data =
5246           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5247       if (!success)
5248         return false;
5249 
5250       std::optional<RegisterInfo> data_reg =
5251           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5252       int32_t offset = address - base_address;
5253       context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, offset);
5254       if (!MemUWrite(context, address, data, addr_byte_size))
5255         return false;
5256     } else {
5257       // MemU[address,4] = bits(32) UNKNOWN;
5258       WriteBits32UnknownToMemory(address);
5259     }
5260 
5261     // if wback then R[n] = offset_addr;
5262     if (wback) {
5263       if (n == 13)
5264         context.type = eContextAdjustStackPointer;
5265       else
5266         context.type = eContextAdjustBaseRegister;
5267       context.SetAddress(offset_addr);
5268 
5269       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5270                                  offset_addr))
5271         return false;
5272     }
5273   }
5274   return true;
5275 }
5276 
5277 // STR (Store Register) calculates an address from a base register value and an
5278 // offset register value, stores a
5279 // word from a register to memory.   The offset register value can optionally
5280 // be shifted.
EmulateSTRRegister(const uint32_t opcode,const ARMEncoding encoding)5281 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5282                                                const ARMEncoding encoding) {
5283 #if 0
5284     if ConditionPassed() then
5285         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5286         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5287         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5288         address = if index then offset_addr else R[n];
5289         if t == 15 then // Only possible for encoding A1
5290             data = PCStoreValue();
5291         else
5292             data = R[t];
5293         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5294             MemU[address,4] = data;
5295         else // Can only occur before ARMv7
5296             MemU[address,4] = bits(32) UNKNOWN;
5297         if wback then R[n] = offset_addr;
5298 #endif
5299 
5300   bool success = false;
5301 
5302   if (ConditionPassed(opcode)) {
5303     const uint32_t addr_byte_size = GetAddressByteSize();
5304 
5305     uint32_t t;
5306     uint32_t n;
5307     uint32_t m;
5308     ARM_ShifterType shift_t;
5309     uint32_t shift_n;
5310     bool index;
5311     bool add;
5312     bool wback;
5313 
5314     // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5315     switch (encoding) {
5316     case eEncodingT1:
5317       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5318       // in ThumbEE";
5319       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5320       t = Bits32(opcode, 2, 0);
5321       n = Bits32(opcode, 5, 3);
5322       m = Bits32(opcode, 8, 6);
5323 
5324       // index = TRUE; add = TRUE; wback = FALSE;
5325       index = true;
5326       add = true;
5327       wback = false;
5328 
5329       // (shift_t, shift_n) = (SRType_LSL, 0);
5330       shift_t = SRType_LSL;
5331       shift_n = 0;
5332       break;
5333 
5334     case eEncodingT2:
5335       // if Rn == '1111' then UNDEFINED;
5336       if (Bits32(opcode, 19, 16) == 15)
5337         return false;
5338 
5339       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5340       t = Bits32(opcode, 15, 12);
5341       n = Bits32(opcode, 19, 16);
5342       m = Bits32(opcode, 3, 0);
5343 
5344       // index = TRUE; add = TRUE; wback = FALSE;
5345       index = true;
5346       add = true;
5347       wback = false;
5348 
5349       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5350       shift_t = SRType_LSL;
5351       shift_n = Bits32(opcode, 5, 4);
5352 
5353       // if t == 15 || BadReg(m) then UNPREDICTABLE;
5354       if ((t == 15) || (BadReg(m)))
5355         return false;
5356       break;
5357 
5358     case eEncodingA1: {
5359       // if P == '0' && W == '1' then SEE STRT;
5360       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5361       t = Bits32(opcode, 15, 12);
5362       n = Bits32(opcode, 19, 16);
5363       m = Bits32(opcode, 3, 0);
5364 
5365       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5366       // (W == '1');
5367       index = BitIsSet(opcode, 24);
5368       add = BitIsSet(opcode, 23);
5369       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5370 
5371       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5372       uint32_t typ = Bits32(opcode, 6, 5);
5373       uint32_t imm5 = Bits32(opcode, 11, 7);
5374       shift_n = DecodeImmShift(typ, imm5, shift_t);
5375 
5376       // if m == 15 then UNPREDICTABLE;
5377       if (m == 15)
5378         return false;
5379 
5380       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5381       if (wback && ((n == 15) || (n == t)))
5382         return false;
5383 
5384       break;
5385     }
5386     default:
5387       return false;
5388     }
5389 
5390     addr_t offset_addr;
5391     addr_t address;
5392     int32_t offset = 0;
5393 
5394     addr_t base_address =
5395         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5396     if (!success)
5397       return false;
5398 
5399     uint32_t Rm_data =
5400         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5401     if (!success)
5402       return false;
5403 
5404     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5405     offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5406     if (!success)
5407       return false;
5408 
5409     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5410     if (add)
5411       offset_addr = base_address + offset;
5412     else
5413       offset_addr = base_address - offset;
5414 
5415     // address = if index then offset_addr else R[n];
5416     if (index)
5417       address = offset_addr;
5418     else
5419       address = base_address;
5420 
5421     uint32_t data;
5422     // if t == 15 then // Only possible for encoding A1
5423     if (t == 15)
5424       // data = PCStoreValue();
5425       data = ReadCoreReg(PC_REG, &success);
5426     else
5427       // data = R[t];
5428       data =
5429           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5430 
5431     if (!success)
5432       return false;
5433 
5434     EmulateInstruction::Context context;
5435     context.type = eContextRegisterStore;
5436 
5437     // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5438     // InstrSet_ARM then
5439     if (UnalignedSupport() ||
5440         (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5441         CurrentInstrSet() == eModeARM) {
5442       // MemU[address,4] = data;
5443 
5444       std::optional<RegisterInfo> base_reg =
5445           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5446       std::optional<RegisterInfo> data_reg =
5447           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5448 
5449       context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5450                                               address - base_address);
5451       if (!MemUWrite(context, address, data, addr_byte_size))
5452         return false;
5453 
5454     } else
5455       // MemU[address,4] = bits(32) UNKNOWN;
5456       WriteBits32UnknownToMemory(address);
5457 
5458     // if wback then R[n] = offset_addr;
5459     if (wback) {
5460       context.type = eContextRegisterLoad;
5461       context.SetAddress(offset_addr);
5462       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5463                                  offset_addr))
5464         return false;
5465     }
5466   }
5467   return true;
5468 }
5469 
EmulateSTRBThumb(const uint32_t opcode,const ARMEncoding encoding)5470 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5471                                              const ARMEncoding encoding) {
5472 #if 0
5473     if ConditionPassed() then
5474         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5475         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5476         address = if index then offset_addr else R[n];
5477         MemU[address,1] = R[t]<7:0>;
5478         if wback then R[n] = offset_addr;
5479 #endif
5480 
5481   bool success = false;
5482 
5483   if (ConditionPassed(opcode)) {
5484     uint32_t t;
5485     uint32_t n;
5486     uint32_t imm32;
5487     bool index;
5488     bool add;
5489     bool wback;
5490     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5491     switch (encoding) {
5492     case eEncodingT1:
5493       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5494       t = Bits32(opcode, 2, 0);
5495       n = Bits32(opcode, 5, 3);
5496       imm32 = Bits32(opcode, 10, 6);
5497 
5498       // index = TRUE; add = TRUE; wback = FALSE;
5499       index = true;
5500       add = true;
5501       wback = false;
5502       break;
5503 
5504     case eEncodingT2:
5505       // if Rn == '1111' then UNDEFINED;
5506       if (Bits32(opcode, 19, 16) == 15)
5507         return false;
5508 
5509       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5510       t = Bits32(opcode, 15, 12);
5511       n = Bits32(opcode, 19, 16);
5512       imm32 = Bits32(opcode, 11, 0);
5513 
5514       // index = TRUE; add = TRUE; wback = FALSE;
5515       index = true;
5516       add = true;
5517       wback = false;
5518 
5519       // if BadReg(t) then UNPREDICTABLE;
5520       if (BadReg(t))
5521         return false;
5522       break;
5523 
5524     case eEncodingT3:
5525       // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5526       // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5527       if (Bits32(opcode, 19, 16) == 15)
5528         return false;
5529 
5530       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5531       t = Bits32(opcode, 15, 12);
5532       n = Bits32(opcode, 19, 16);
5533       imm32 = Bits32(opcode, 7, 0);
5534 
5535       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5536       index = BitIsSet(opcode, 10);
5537       add = BitIsSet(opcode, 9);
5538       wback = BitIsSet(opcode, 8);
5539 
5540       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5541       if ((BadReg(t)) || (wback && (n == t)))
5542         return false;
5543       break;
5544 
5545     default:
5546       return false;
5547     }
5548 
5549     addr_t offset_addr;
5550     addr_t address;
5551     addr_t base_address =
5552         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5553     if (!success)
5554       return false;
5555 
5556     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5557     if (add)
5558       offset_addr = base_address + imm32;
5559     else
5560       offset_addr = base_address - imm32;
5561 
5562     // address = if index then offset_addr else R[n];
5563     if (index)
5564       address = offset_addr;
5565     else
5566       address = base_address;
5567 
5568     // MemU[address,1] = R[t]<7:0>
5569     std::optional<RegisterInfo> base_reg =
5570         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5571     std::optional<RegisterInfo> data_reg =
5572         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5573 
5574     EmulateInstruction::Context context;
5575     context.type = eContextRegisterStore;
5576     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
5577                                             address - base_address);
5578 
5579     uint32_t data =
5580         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5581     if (!success)
5582       return false;
5583 
5584     data = Bits32(data, 7, 0);
5585 
5586     if (!MemUWrite(context, address, data, 1))
5587       return false;
5588 
5589     // if wback then R[n] = offset_addr;
5590     if (wback) {
5591       context.type = eContextRegisterLoad;
5592       context.SetAddress(offset_addr);
5593       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5594                                  offset_addr))
5595         return false;
5596     }
5597   }
5598 
5599   return true;
5600 }
5601 
5602 // STRH (register) calculates an address from a base register value and an
5603 // offset register value, and stores a
5604 // halfword from a register to memory.  The offset register value can be
5605 // shifted left by 0, 1, 2, or 3 bits.
EmulateSTRHRegister(const uint32_t opcode,const ARMEncoding encoding)5606 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5607                                                 const ARMEncoding encoding) {
5608 #if 0
5609     if ConditionPassed() then
5610         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5611         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5612         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5613         address = if index then offset_addr else R[n];
5614         if UnalignedSupport() || address<0> == '0' then
5615             MemU[address,2] = R[t]<15:0>;
5616         else // Can only occur before ARMv7
5617             MemU[address,2] = bits(16) UNKNOWN;
5618         if wback then R[n] = offset_addr;
5619 #endif
5620 
5621   bool success = false;
5622 
5623   if (ConditionPassed(opcode)) {
5624     uint32_t t;
5625     uint32_t n;
5626     uint32_t m;
5627     bool index;
5628     bool add;
5629     bool wback;
5630     ARM_ShifterType shift_t;
5631     uint32_t shift_n;
5632 
5633     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5634     switch (encoding) {
5635     case eEncodingT1:
5636       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5637       // in ThumbEE";
5638       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5639       t = Bits32(opcode, 2, 0);
5640       n = Bits32(opcode, 5, 3);
5641       m = Bits32(opcode, 8, 6);
5642 
5643       // index = TRUE; add = TRUE; wback = FALSE;
5644       index = true;
5645       add = true;
5646       wback = false;
5647 
5648       // (shift_t, shift_n) = (SRType_LSL, 0);
5649       shift_t = SRType_LSL;
5650       shift_n = 0;
5651 
5652       break;
5653 
5654     case eEncodingT2:
5655       // if Rn == '1111' then UNDEFINED;
5656       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5657       t = Bits32(opcode, 15, 12);
5658       n = Bits32(opcode, 19, 16);
5659       m = Bits32(opcode, 3, 0);
5660       if (n == 15)
5661         return false;
5662 
5663       // index = TRUE; add = TRUE; wback = FALSE;
5664       index = true;
5665       add = true;
5666       wback = false;
5667 
5668       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5669       shift_t = SRType_LSL;
5670       shift_n = Bits32(opcode, 5, 4);
5671 
5672       // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5673       if (BadReg(t) || BadReg(m))
5674         return false;
5675 
5676       break;
5677 
5678     case eEncodingA1:
5679       // if P == '0' && W == '1' then SEE STRHT;
5680       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5681       t = Bits32(opcode, 15, 12);
5682       n = Bits32(opcode, 19, 16);
5683       m = Bits32(opcode, 3, 0);
5684 
5685       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5686       // (W == '1');
5687       index = BitIsSet(opcode, 24);
5688       add = BitIsSet(opcode, 23);
5689       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5690 
5691       // (shift_t, shift_n) = (SRType_LSL, 0);
5692       shift_t = SRType_LSL;
5693       shift_n = 0;
5694 
5695       // if t == 15 || m == 15 then UNPREDICTABLE;
5696       if ((t == 15) || (m == 15))
5697         return false;
5698 
5699       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5700       if (wback && ((n == 15) || (n == t)))
5701         return false;
5702 
5703       break;
5704 
5705     default:
5706       return false;
5707     }
5708 
5709     uint32_t Rm = ReadCoreReg(m, &success);
5710     if (!success)
5711       return false;
5712 
5713     uint32_t Rn = ReadCoreReg(n, &success);
5714     if (!success)
5715       return false;
5716 
5717     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5718     uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5719     if (!success)
5720       return false;
5721 
5722     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5723     addr_t offset_addr;
5724     if (add)
5725       offset_addr = Rn + offset;
5726     else
5727       offset_addr = Rn - offset;
5728 
5729     // address = if index then offset_addr else R[n];
5730     addr_t address;
5731     if (index)
5732       address = offset_addr;
5733     else
5734       address = Rn;
5735 
5736     EmulateInstruction::Context context;
5737     context.type = eContextRegisterStore;
5738 
5739     // if UnalignedSupport() || address<0> == '0' then
5740     if (UnalignedSupport() || BitIsClear(address, 0)) {
5741       // MemU[address,2] = R[t]<15:0>;
5742       uint32_t Rt = ReadCoreReg(t, &success);
5743       if (!success)
5744         return false;
5745 
5746       EmulateInstruction::Context context;
5747       context.type = eContextRegisterStore;
5748       std::optional<RegisterInfo> base_reg =
5749           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
5750       std::optional<RegisterInfo> offset_reg =
5751           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
5752       std::optional<RegisterInfo> data_reg =
5753           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
5754       context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
5755                                                       *data_reg);
5756 
5757       if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5758         return false;
5759     } else // Can only occur before ARMv7
5760     {
5761       // MemU[address,2] = bits(16) UNKNOWN;
5762     }
5763 
5764     // if wback then R[n] = offset_addr;
5765     if (wback) {
5766       context.type = eContextAdjustBaseRegister;
5767       context.SetAddress(offset_addr);
5768       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5769                                  offset_addr))
5770         return false;
5771     }
5772   }
5773 
5774   return true;
5775 }
5776 
5777 // Add with Carry (immediate) adds an immediate value and the carry flag value
5778 // to a register value, and writes the result to the destination register.  It
5779 // can optionally update the condition flags based on the result.
EmulateADCImm(const uint32_t opcode,const ARMEncoding encoding)5780 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5781                                           const ARMEncoding encoding) {
5782 #if 0
5783     // ARM pseudo code...
5784     if ConditionPassed() then
5785         EncodingSpecificOperations();
5786         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5787         if d == 15 then         // Can only occur for ARM encoding
5788             ALUWritePC(result); // setflags is always FALSE here
5789         else
5790             R[d] = result;
5791             if setflags then
5792                 APSR.N = result<31>;
5793                 APSR.Z = IsZeroBit(result);
5794                 APSR.C = carry;
5795                 APSR.V = overflow;
5796 #endif
5797 
5798   bool success = false;
5799 
5800   if (ConditionPassed(opcode)) {
5801     uint32_t Rd, Rn;
5802     uint32_t
5803         imm32; // the immediate value to be added to the value obtained from Rn
5804     bool setflags;
5805     switch (encoding) {
5806     case eEncodingT1:
5807       Rd = Bits32(opcode, 11, 8);
5808       Rn = Bits32(opcode, 19, 16);
5809       setflags = BitIsSet(opcode, 20);
5810       imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5811       if (BadReg(Rd) || BadReg(Rn))
5812         return false;
5813       break;
5814     case eEncodingA1:
5815       Rd = Bits32(opcode, 15, 12);
5816       Rn = Bits32(opcode, 19, 16);
5817       setflags = BitIsSet(opcode, 20);
5818       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5819 
5820       if (Rd == 15 && setflags)
5821         return EmulateSUBSPcLrEtc(opcode, encoding);
5822       break;
5823     default:
5824       return false;
5825     }
5826 
5827     // Read the first operand.
5828     int32_t val1 = ReadCoreReg(Rn, &success);
5829     if (!success)
5830       return false;
5831 
5832     AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5833 
5834     EmulateInstruction::Context context;
5835     context.type = EmulateInstruction::eContextImmediate;
5836     context.SetNoArgs();
5837 
5838     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5839                                    res.carry_out, res.overflow))
5840       return false;
5841   }
5842   return true;
5843 }
5844 
5845 // Add with Carry (register) adds a register value, the carry flag value, and
5846 // an optionally-shifted register value, and writes the result to the
5847 // destination register.  It can optionally update the condition flags based on
5848 // the result.
EmulateADCReg(const uint32_t opcode,const ARMEncoding encoding)5849 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5850                                           const ARMEncoding encoding) {
5851 #if 0
5852     // ARM pseudo code...
5853     if ConditionPassed() then
5854         EncodingSpecificOperations();
5855         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5856         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5857         if d == 15 then         // Can only occur for ARM encoding
5858             ALUWritePC(result); // setflags is always FALSE here
5859         else
5860             R[d] = result;
5861             if setflags then
5862                 APSR.N = result<31>;
5863                 APSR.Z = IsZeroBit(result);
5864                 APSR.C = carry;
5865                 APSR.V = overflow;
5866 #endif
5867 
5868   bool success = false;
5869 
5870   if (ConditionPassed(opcode)) {
5871     uint32_t Rd, Rn, Rm;
5872     ARM_ShifterType shift_t;
5873     uint32_t shift_n; // the shift applied to the value read from Rm
5874     bool setflags;
5875     switch (encoding) {
5876     case eEncodingT1:
5877       Rd = Rn = Bits32(opcode, 2, 0);
5878       Rm = Bits32(opcode, 5, 3);
5879       setflags = !InITBlock();
5880       shift_t = SRType_LSL;
5881       shift_n = 0;
5882       break;
5883     case eEncodingT2:
5884       Rd = Bits32(opcode, 11, 8);
5885       Rn = Bits32(opcode, 19, 16);
5886       Rm = Bits32(opcode, 3, 0);
5887       setflags = BitIsSet(opcode, 20);
5888       shift_n = DecodeImmShiftThumb(opcode, shift_t);
5889       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5890         return false;
5891       break;
5892     case eEncodingA1:
5893       Rd = Bits32(opcode, 15, 12);
5894       Rn = Bits32(opcode, 19, 16);
5895       Rm = Bits32(opcode, 3, 0);
5896       setflags = BitIsSet(opcode, 20);
5897       shift_n = DecodeImmShiftARM(opcode, shift_t);
5898 
5899       if (Rd == 15 && setflags)
5900         return EmulateSUBSPcLrEtc(opcode, encoding);
5901       break;
5902     default:
5903       return false;
5904     }
5905 
5906     // Read the first operand.
5907     int32_t val1 = ReadCoreReg(Rn, &success);
5908     if (!success)
5909       return false;
5910 
5911     // Read the second operand.
5912     int32_t val2 = ReadCoreReg(Rm, &success);
5913     if (!success)
5914       return false;
5915 
5916     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5917     if (!success)
5918       return false;
5919     AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5920 
5921     EmulateInstruction::Context context;
5922     context.type = EmulateInstruction::eContextImmediate;
5923     context.SetNoArgs();
5924 
5925     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5926                                    res.carry_out, res.overflow))
5927       return false;
5928   }
5929   return true;
5930 }
5931 
5932 // This instruction adds an immediate value to the PC value to form a PC-
5933 // relative address, and writes the result to the destination register.
EmulateADR(const uint32_t opcode,const ARMEncoding encoding)5934 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5935                                        const ARMEncoding encoding) {
5936 #if 0
5937     // ARM pseudo code...
5938     if ConditionPassed() then
5939         EncodingSpecificOperations();
5940         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5941         if d == 15 then         // Can only occur for ARM encodings
5942             ALUWritePC(result);
5943         else
5944             R[d] = result;
5945 #endif
5946 
5947   bool success = false;
5948 
5949   if (ConditionPassed(opcode)) {
5950     uint32_t Rd;
5951     uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5952     bool add;
5953     switch (encoding) {
5954     case eEncodingT1:
5955       Rd = Bits32(opcode, 10, 8);
5956       imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5957       add = true;
5958       break;
5959     case eEncodingT2:
5960     case eEncodingT3:
5961       Rd = Bits32(opcode, 11, 8);
5962       imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5963       add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5964       if (BadReg(Rd))
5965         return false;
5966       break;
5967     case eEncodingA1:
5968     case eEncodingA2:
5969       Rd = Bits32(opcode, 15, 12);
5970       imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
5971       add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5972       break;
5973     default:
5974       return false;
5975     }
5976 
5977     // Read the PC value.
5978     uint32_t pc = ReadCoreReg(PC_REG, &success);
5979     if (!success)
5980       return false;
5981 
5982     uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5983 
5984     EmulateInstruction::Context context;
5985     context.type = EmulateInstruction::eContextImmediate;
5986     context.SetNoArgs();
5987 
5988     if (!WriteCoreReg(context, result, Rd))
5989       return false;
5990   }
5991   return true;
5992 }
5993 
5994 // This instruction performs a bitwise AND of a register value and an immediate
5995 // value, and writes the result to the destination register.  It can optionally
5996 // update the condition flags based on the result.
EmulateANDImm(const uint32_t opcode,const ARMEncoding encoding)5997 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
5998                                           const ARMEncoding encoding) {
5999 #if 0
6000     // ARM pseudo code...
6001     if ConditionPassed() then
6002         EncodingSpecificOperations();
6003         result = R[n] AND imm32;
6004         if d == 15 then         // Can only occur for ARM encoding
6005             ALUWritePC(result); // setflags is always FALSE here
6006         else
6007             R[d] = result;
6008             if setflags then
6009                 APSR.N = result<31>;
6010                 APSR.Z = IsZeroBit(result);
6011                 APSR.C = carry;
6012                 // APSR.V unchanged
6013 #endif
6014 
6015   bool success = false;
6016 
6017   if (ConditionPassed(opcode)) {
6018     uint32_t Rd, Rn;
6019     uint32_t
6020         imm32; // the immediate value to be ANDed to the value obtained from Rn
6021     bool setflags;
6022     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6023     switch (encoding) {
6024     case eEncodingT1:
6025       Rd = Bits32(opcode, 11, 8);
6026       Rn = Bits32(opcode, 19, 16);
6027       setflags = BitIsSet(opcode, 20);
6028       imm32 = ThumbExpandImm_C(
6029           opcode, APSR_C,
6030           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6031       // if Rd == '1111' && S == '1' then SEE TST (immediate);
6032       if (Rd == 15 && setflags)
6033         return EmulateTSTImm(opcode, eEncodingT1);
6034       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6035         return false;
6036       break;
6037     case eEncodingA1:
6038       Rd = Bits32(opcode, 15, 12);
6039       Rn = Bits32(opcode, 19, 16);
6040       setflags = BitIsSet(opcode, 20);
6041       imm32 =
6042           ARMExpandImm_C(opcode, APSR_C,
6043                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6044 
6045       if (Rd == 15 && setflags)
6046         return EmulateSUBSPcLrEtc(opcode, encoding);
6047       break;
6048     default:
6049       return false;
6050     }
6051 
6052     // Read the first operand.
6053     uint32_t val1 = ReadCoreReg(Rn, &success);
6054     if (!success)
6055       return false;
6056 
6057     uint32_t result = val1 & imm32;
6058 
6059     EmulateInstruction::Context context;
6060     context.type = EmulateInstruction::eContextImmediate;
6061     context.SetNoArgs();
6062 
6063     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6064       return false;
6065   }
6066   return true;
6067 }
6068 
6069 // This instruction performs a bitwise AND of a register value and an
6070 // optionally-shifted register value, and writes the result to the destination
6071 // register.  It can optionally update the condition flags based on the result.
EmulateANDReg(const uint32_t opcode,const ARMEncoding encoding)6072 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6073                                           const ARMEncoding encoding) {
6074 #if 0
6075     // ARM pseudo code...
6076     if ConditionPassed() then
6077         EncodingSpecificOperations();
6078         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6079         result = R[n] AND shifted;
6080         if d == 15 then         // Can only occur for ARM encoding
6081             ALUWritePC(result); // setflags is always FALSE here
6082         else
6083             R[d] = result;
6084             if setflags then
6085                 APSR.N = result<31>;
6086                 APSR.Z = IsZeroBit(result);
6087                 APSR.C = carry;
6088                 // APSR.V unchanged
6089 #endif
6090 
6091   bool success = false;
6092 
6093   if (ConditionPassed(opcode)) {
6094     uint32_t Rd, Rn, Rm;
6095     ARM_ShifterType shift_t;
6096     uint32_t shift_n; // the shift applied to the value read from Rm
6097     bool setflags;
6098     uint32_t carry;
6099     switch (encoding) {
6100     case eEncodingT1:
6101       Rd = Rn = Bits32(opcode, 2, 0);
6102       Rm = Bits32(opcode, 5, 3);
6103       setflags = !InITBlock();
6104       shift_t = SRType_LSL;
6105       shift_n = 0;
6106       break;
6107     case eEncodingT2:
6108       Rd = Bits32(opcode, 11, 8);
6109       Rn = Bits32(opcode, 19, 16);
6110       Rm = Bits32(opcode, 3, 0);
6111       setflags = BitIsSet(opcode, 20);
6112       shift_n = DecodeImmShiftThumb(opcode, shift_t);
6113       // if Rd == '1111' && S == '1' then SEE TST (register);
6114       if (Rd == 15 && setflags)
6115         return EmulateTSTReg(opcode, eEncodingT2);
6116       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6117         return false;
6118       break;
6119     case eEncodingA1:
6120       Rd = Bits32(opcode, 15, 12);
6121       Rn = Bits32(opcode, 19, 16);
6122       Rm = Bits32(opcode, 3, 0);
6123       setflags = BitIsSet(opcode, 20);
6124       shift_n = DecodeImmShiftARM(opcode, shift_t);
6125 
6126       if (Rd == 15 && setflags)
6127         return EmulateSUBSPcLrEtc(opcode, encoding);
6128       break;
6129     default:
6130       return false;
6131     }
6132 
6133     // Read the first operand.
6134     uint32_t val1 = ReadCoreReg(Rn, &success);
6135     if (!success)
6136       return false;
6137 
6138     // Read the second operand.
6139     uint32_t val2 = ReadCoreReg(Rm, &success);
6140     if (!success)
6141       return false;
6142 
6143     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6144     if (!success)
6145       return false;
6146     uint32_t result = val1 & shifted;
6147 
6148     EmulateInstruction::Context context;
6149     context.type = EmulateInstruction::eContextImmediate;
6150     context.SetNoArgs();
6151 
6152     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6153       return false;
6154   }
6155   return true;
6156 }
6157 
6158 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6159 // the complement of an immediate value, and writes the result to the
6160 // destination register.  It can optionally update the condition flags based on
6161 // the result.
EmulateBICImm(const uint32_t opcode,const ARMEncoding encoding)6162 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6163                                           const ARMEncoding encoding) {
6164 #if 0
6165     // ARM pseudo code...
6166     if ConditionPassed() then
6167         EncodingSpecificOperations();
6168         result = R[n] AND NOT(imm32);
6169         if d == 15 then         // Can only occur for ARM encoding
6170             ALUWritePC(result); // setflags is always FALSE here
6171         else
6172             R[d] = result;
6173             if setflags then
6174                 APSR.N = result<31>;
6175                 APSR.Z = IsZeroBit(result);
6176                 APSR.C = carry;
6177                 // APSR.V unchanged
6178 #endif
6179 
6180   bool success = false;
6181 
6182   if (ConditionPassed(opcode)) {
6183     uint32_t Rd, Rn;
6184     uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6185                     // the value obtained from Rn
6186     bool setflags;
6187     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6188     switch (encoding) {
6189     case eEncodingT1:
6190       Rd = Bits32(opcode, 11, 8);
6191       Rn = Bits32(opcode, 19, 16);
6192       setflags = BitIsSet(opcode, 20);
6193       imm32 = ThumbExpandImm_C(
6194           opcode, APSR_C,
6195           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6196       if (BadReg(Rd) || BadReg(Rn))
6197         return false;
6198       break;
6199     case eEncodingA1:
6200       Rd = Bits32(opcode, 15, 12);
6201       Rn = Bits32(opcode, 19, 16);
6202       setflags = BitIsSet(opcode, 20);
6203       imm32 =
6204           ARMExpandImm_C(opcode, APSR_C,
6205                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6206 
6207       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6208       // instructions;
6209       if (Rd == 15 && setflags)
6210         return EmulateSUBSPcLrEtc(opcode, encoding);
6211       break;
6212     default:
6213       return false;
6214     }
6215 
6216     // Read the first operand.
6217     uint32_t val1 = ReadCoreReg(Rn, &success);
6218     if (!success)
6219       return false;
6220 
6221     uint32_t result = val1 & ~imm32;
6222 
6223     EmulateInstruction::Context context;
6224     context.type = EmulateInstruction::eContextImmediate;
6225     context.SetNoArgs();
6226 
6227     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6228       return false;
6229   }
6230   return true;
6231 }
6232 
6233 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6234 // the complement of an optionally-shifted register value, and writes the
6235 // result to the destination register. It can optionally update the condition
6236 // flags based on the result.
EmulateBICReg(const uint32_t opcode,const ARMEncoding encoding)6237 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6238                                           const ARMEncoding encoding) {
6239 #if 0
6240     // ARM pseudo code...
6241     if ConditionPassed() then
6242         EncodingSpecificOperations();
6243         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6244         result = R[n] AND NOT(shifted);
6245         if d == 15 then         // Can only occur for ARM encoding
6246             ALUWritePC(result); // setflags is always FALSE here
6247         else
6248             R[d] = result;
6249             if setflags then
6250                 APSR.N = result<31>;
6251                 APSR.Z = IsZeroBit(result);
6252                 APSR.C = carry;
6253                 // APSR.V unchanged
6254 #endif
6255 
6256   bool success = false;
6257 
6258   if (ConditionPassed(opcode)) {
6259     uint32_t Rd, Rn, Rm;
6260     ARM_ShifterType shift_t;
6261     uint32_t shift_n; // the shift applied to the value read from Rm
6262     bool setflags;
6263     uint32_t carry;
6264     switch (encoding) {
6265     case eEncodingT1:
6266       Rd = Rn = Bits32(opcode, 2, 0);
6267       Rm = Bits32(opcode, 5, 3);
6268       setflags = !InITBlock();
6269       shift_t = SRType_LSL;
6270       shift_n = 0;
6271       break;
6272     case eEncodingT2:
6273       Rd = Bits32(opcode, 11, 8);
6274       Rn = Bits32(opcode, 19, 16);
6275       Rm = Bits32(opcode, 3, 0);
6276       setflags = BitIsSet(opcode, 20);
6277       shift_n = DecodeImmShiftThumb(opcode, shift_t);
6278       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6279         return false;
6280       break;
6281     case eEncodingA1:
6282       Rd = Bits32(opcode, 15, 12);
6283       Rn = Bits32(opcode, 19, 16);
6284       Rm = Bits32(opcode, 3, 0);
6285       setflags = BitIsSet(opcode, 20);
6286       shift_n = DecodeImmShiftARM(opcode, shift_t);
6287 
6288       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6289       // instructions;
6290       if (Rd == 15 && setflags)
6291         return EmulateSUBSPcLrEtc(opcode, encoding);
6292       break;
6293     default:
6294       return false;
6295     }
6296 
6297     // Read the first operand.
6298     uint32_t val1 = ReadCoreReg(Rn, &success);
6299     if (!success)
6300       return false;
6301 
6302     // Read the second operand.
6303     uint32_t val2 = ReadCoreReg(Rm, &success);
6304     if (!success)
6305       return false;
6306 
6307     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6308     if (!success)
6309       return false;
6310     uint32_t result = val1 & ~shifted;
6311 
6312     EmulateInstruction::Context context;
6313     context.type = EmulateInstruction::eContextImmediate;
6314     context.SetNoArgs();
6315 
6316     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6317       return false;
6318   }
6319   return true;
6320 }
6321 
6322 // LDR (immediate, ARM) calculates an address from a base register value and an
6323 // immediate offset, loads a word
6324 // from memory, and writes it to a register.  It can use offset, post-indexed,
6325 // or pre-indexed addressing.
EmulateLDRImmediateARM(const uint32_t opcode,const ARMEncoding encoding)6326 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6327                                                    const ARMEncoding encoding) {
6328 #if 0
6329     if ConditionPassed() then
6330         EncodingSpecificOperations();
6331         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6332         address = if index then offset_addr else R[n];
6333         data = MemU[address,4];
6334         if wback then R[n] = offset_addr;
6335         if t == 15 then
6336             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6337         elsif UnalignedSupport() || address<1:0> = '00' then
6338             R[t] = data;
6339         else // Can only apply before ARMv7
6340             R[t] = ROR(data, 8*UInt(address<1:0>));
6341 #endif
6342 
6343   bool success = false;
6344 
6345   if (ConditionPassed(opcode)) {
6346     const uint32_t addr_byte_size = GetAddressByteSize();
6347 
6348     uint32_t t;
6349     uint32_t n;
6350     uint32_t imm32;
6351     bool index;
6352     bool add;
6353     bool wback;
6354 
6355     switch (encoding) {
6356     case eEncodingA1:
6357       // if Rn == '1111' then SEE LDR (literal);
6358       // if P == '0' && W == '1' then SEE LDRT;
6359       // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6360       // '000000000100' then SEE POP;
6361       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6362       t = Bits32(opcode, 15, 12);
6363       n = Bits32(opcode, 19, 16);
6364       imm32 = Bits32(opcode, 11, 0);
6365 
6366       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6367       // (W == '1');
6368       index = BitIsSet(opcode, 24);
6369       add = BitIsSet(opcode, 23);
6370       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6371 
6372       // if wback && n == t then UNPREDICTABLE;
6373       if (wback && (n == t))
6374         return false;
6375 
6376       break;
6377 
6378     default:
6379       return false;
6380     }
6381 
6382     addr_t address;
6383     addr_t offset_addr;
6384     addr_t base_address = ReadCoreReg(n, &success);
6385     if (!success)
6386       return false;
6387 
6388     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6389     if (add)
6390       offset_addr = base_address + imm32;
6391     else
6392       offset_addr = base_address - imm32;
6393 
6394     // address = if index then offset_addr else R[n];
6395     if (index)
6396       address = offset_addr;
6397     else
6398       address = base_address;
6399 
6400     // data = MemU[address,4];
6401 
6402     std::optional<RegisterInfo> base_reg =
6403         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6404     EmulateInstruction::Context context;
6405     context.type = eContextRegisterLoad;
6406     context.SetRegisterPlusOffset(*base_reg, address - base_address);
6407 
6408     uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6409     if (!success)
6410       return false;
6411 
6412     // if wback then R[n] = offset_addr;
6413     if (wback) {
6414       context.type = eContextAdjustBaseRegister;
6415       context.SetAddress(offset_addr);
6416       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6417                                  offset_addr))
6418         return false;
6419     }
6420 
6421     // if t == 15 then
6422     if (t == 15) {
6423       // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6424       if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6425         // LoadWritePC (data);
6426         context.type = eContextRegisterLoad;
6427         context.SetRegisterPlusOffset(*base_reg, address - base_address);
6428         LoadWritePC(context, data);
6429       } else
6430         return false;
6431     }
6432     // elsif UnalignedSupport() || address<1:0> = '00' then
6433     else if (UnalignedSupport() ||
6434              (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6435       // R[t] = data;
6436       context.type = eContextRegisterLoad;
6437       context.SetRegisterPlusOffset(*base_reg, address - base_address);
6438       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6439                                  data))
6440         return false;
6441     }
6442     // else // Can only apply before ARMv7
6443     else {
6444       // R[t] = ROR(data, 8*UInt(address<1:0>));
6445       data = ROR(data, Bits32(address, 1, 0), &success);
6446       if (!success)
6447         return false;
6448       context.type = eContextRegisterLoad;
6449       context.SetImmediate(data);
6450       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6451                                  data))
6452         return false;
6453     }
6454   }
6455   return true;
6456 }
6457 
6458 // LDR (register) calculates an address from a base register value and an offset
6459 // register value, loads a word
6460 // from memory, and writes it to a register.  The offset register value can
6461 // optionally be shifted.
EmulateLDRRegister(const uint32_t opcode,const ARMEncoding encoding)6462 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6463                                                const ARMEncoding encoding) {
6464 #if 0
6465     if ConditionPassed() then
6466         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6467         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6468         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6469         address = if index then offset_addr else R[n];
6470         data = MemU[address,4];
6471         if wback then R[n] = offset_addr;
6472         if t == 15 then
6473             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6474         elsif UnalignedSupport() || address<1:0> = '00' then
6475             R[t] = data;
6476         else // Can only apply before ARMv7
6477             if CurrentInstrSet() == InstrSet_ARM then
6478                 R[t] = ROR(data, 8*UInt(address<1:0>));
6479             else
6480                 R[t] = bits(32) UNKNOWN;
6481 #endif
6482 
6483   bool success = false;
6484 
6485   if (ConditionPassed(opcode)) {
6486     const uint32_t addr_byte_size = GetAddressByteSize();
6487 
6488     uint32_t t;
6489     uint32_t n;
6490     uint32_t m;
6491     bool index;
6492     bool add;
6493     bool wback;
6494     ARM_ShifterType shift_t;
6495     uint32_t shift_n;
6496 
6497     switch (encoding) {
6498     case eEncodingT1:
6499       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6500       // in ThumbEE";
6501       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6502       t = Bits32(opcode, 2, 0);
6503       n = Bits32(opcode, 5, 3);
6504       m = Bits32(opcode, 8, 6);
6505 
6506       // index = TRUE; add = TRUE; wback = FALSE;
6507       index = true;
6508       add = true;
6509       wback = false;
6510 
6511       // (shift_t, shift_n) = (SRType_LSL, 0);
6512       shift_t = SRType_LSL;
6513       shift_n = 0;
6514 
6515       break;
6516 
6517     case eEncodingT2:
6518       // if Rn == '1111' then SEE LDR (literal);
6519       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6520       t = Bits32(opcode, 15, 12);
6521       n = Bits32(opcode, 19, 16);
6522       m = Bits32(opcode, 3, 0);
6523 
6524       // index = TRUE; add = TRUE; wback = FALSE;
6525       index = true;
6526       add = true;
6527       wback = false;
6528 
6529       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6530       shift_t = SRType_LSL;
6531       shift_n = Bits32(opcode, 5, 4);
6532 
6533       // if BadReg(m) then UNPREDICTABLE;
6534       if (BadReg(m))
6535         return false;
6536 
6537       // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6538       if ((t == 15) && InITBlock() && !LastInITBlock())
6539         return false;
6540 
6541       break;
6542 
6543     case eEncodingA1: {
6544       // if P == '0' && W == '1' then SEE LDRT;
6545       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6546       t = Bits32(opcode, 15, 12);
6547       n = Bits32(opcode, 19, 16);
6548       m = Bits32(opcode, 3, 0);
6549 
6550       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6551       // (W == '1');
6552       index = BitIsSet(opcode, 24);
6553       add = BitIsSet(opcode, 23);
6554       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6555 
6556       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6557       uint32_t type = Bits32(opcode, 6, 5);
6558       uint32_t imm5 = Bits32(opcode, 11, 7);
6559       shift_n = DecodeImmShift(type, imm5, shift_t);
6560 
6561       // if m == 15 then UNPREDICTABLE;
6562       if (m == 15)
6563         return false;
6564 
6565       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6566       if (wback && ((n == 15) || (n == t)))
6567         return false;
6568     } break;
6569 
6570     default:
6571       return false;
6572     }
6573 
6574     uint32_t Rm =
6575         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6576     if (!success)
6577       return false;
6578 
6579     uint32_t Rn =
6580         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6581     if (!success)
6582       return false;
6583 
6584     addr_t offset_addr;
6585     addr_t address;
6586 
6587     // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is
6588     // an application level alias for the CPSR".
6589     addr_t offset =
6590         Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6591     if (!success)
6592       return false;
6593 
6594     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6595     if (add)
6596       offset_addr = Rn + offset;
6597     else
6598       offset_addr = Rn - offset;
6599 
6600     // address = if index then offset_addr else R[n];
6601     if (index)
6602       address = offset_addr;
6603     else
6604       address = Rn;
6605 
6606     // data = MemU[address,4];
6607     std::optional<RegisterInfo> base_reg =
6608         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6609     EmulateInstruction::Context context;
6610     context.type = eContextRegisterLoad;
6611     context.SetRegisterPlusOffset(*base_reg, address - Rn);
6612 
6613     uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6614     if (!success)
6615       return false;
6616 
6617     // if wback then R[n] = offset_addr;
6618     if (wback) {
6619       context.type = eContextAdjustBaseRegister;
6620       context.SetAddress(offset_addr);
6621       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6622                                  offset_addr))
6623         return false;
6624     }
6625 
6626     // if t == 15 then
6627     if (t == 15) {
6628       // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6629       if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6630         context.type = eContextRegisterLoad;
6631         context.SetRegisterPlusOffset(*base_reg, address - Rn);
6632         LoadWritePC(context, data);
6633       } else
6634         return false;
6635     }
6636     // elsif UnalignedSupport() || address<1:0> = '00' then
6637     else if (UnalignedSupport() ||
6638              (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6639       // R[t] = data;
6640       context.type = eContextRegisterLoad;
6641       context.SetRegisterPlusOffset(*base_reg, address - Rn);
6642       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6643                                  data))
6644         return false;
6645     } else // Can only apply before ARMv7
6646     {
6647       // if CurrentInstrSet() == InstrSet_ARM then
6648       if (CurrentInstrSet() == eModeARM) {
6649         // R[t] = ROR(data, 8*UInt(address<1:0>));
6650         data = ROR(data, Bits32(address, 1, 0), &success);
6651         if (!success)
6652           return false;
6653         context.type = eContextRegisterLoad;
6654         context.SetImmediate(data);
6655         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6656                                    data))
6657           return false;
6658       } else {
6659         // R[t] = bits(32) UNKNOWN;
6660         WriteBits32Unknown(t);
6661       }
6662     }
6663   }
6664   return true;
6665 }
6666 
6667 // LDRB (immediate, Thumb)
EmulateLDRBImmediate(const uint32_t opcode,const ARMEncoding encoding)6668 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6669                                                  const ARMEncoding encoding) {
6670 #if 0
6671     if ConditionPassed() then
6672         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6673         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6674         address = if index then offset_addr else R[n];
6675         R[t] = ZeroExtend(MemU[address,1], 32);
6676         if wback then R[n] = offset_addr;
6677 #endif
6678 
6679   bool success = false;
6680 
6681   if (ConditionPassed(opcode)) {
6682     uint32_t t;
6683     uint32_t n;
6684     uint32_t imm32;
6685     bool index;
6686     bool add;
6687     bool wback;
6688 
6689     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6690     switch (encoding) {
6691     case eEncodingT1:
6692       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6693       t = Bits32(opcode, 2, 0);
6694       n = Bits32(opcode, 5, 3);
6695       imm32 = Bits32(opcode, 10, 6);
6696 
6697       // index = TRUE; add = TRUE; wback = FALSE;
6698       index = true;
6699       add = true;
6700       wback = false;
6701 
6702       break;
6703 
6704     case eEncodingT2:
6705       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6706       t = Bits32(opcode, 15, 12);
6707       n = Bits32(opcode, 19, 16);
6708       imm32 = Bits32(opcode, 11, 0);
6709 
6710       // index = TRUE; add = TRUE; wback = FALSE;
6711       index = true;
6712       add = true;
6713       wback = false;
6714 
6715       // if Rt == '1111' then SEE PLD;
6716       if (t == 15)
6717         return false; // PLD is not implemented yet
6718 
6719       // if Rn == '1111' then SEE LDRB (literal);
6720       if (n == 15)
6721         return EmulateLDRBLiteral(opcode, eEncodingT1);
6722 
6723       // if t == 13 then UNPREDICTABLE;
6724       if (t == 13)
6725         return false;
6726 
6727       break;
6728 
6729     case eEncodingT3:
6730       // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6731       // if P == '0' && W == '0' then UNDEFINED;
6732       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6733         return false;
6734 
6735       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6736       t = Bits32(opcode, 15, 12);
6737       n = Bits32(opcode, 19, 16);
6738       imm32 = Bits32(opcode, 7, 0);
6739 
6740       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6741       index = BitIsSet(opcode, 10);
6742       add = BitIsSet(opcode, 9);
6743       wback = BitIsSet(opcode, 8);
6744 
6745       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6746       if (t == 15)
6747         return false; // PLD is not implemented yet
6748 
6749       // if Rn == '1111' then SEE LDRB (literal);
6750       if (n == 15)
6751         return EmulateLDRBLiteral(opcode, eEncodingT1);
6752 
6753       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6754       if (BadReg(t) || (wback && (n == t)))
6755         return false;
6756 
6757       break;
6758 
6759     default:
6760       return false;
6761     }
6762 
6763     uint32_t Rn =
6764         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6765     if (!success)
6766       return false;
6767 
6768     addr_t address;
6769     addr_t offset_addr;
6770 
6771     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6772     if (add)
6773       offset_addr = Rn + imm32;
6774     else
6775       offset_addr = Rn - imm32;
6776 
6777     // address = if index then offset_addr else R[n];
6778     if (index)
6779       address = offset_addr;
6780     else
6781       address = Rn;
6782 
6783     // R[t] = ZeroExtend(MemU[address,1], 32);
6784     std::optional<RegisterInfo> base_reg =
6785         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
6786     std::optional<RegisterInfo> data_reg =
6787         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
6788 
6789     EmulateInstruction::Context context;
6790     context.type = eContextRegisterLoad;
6791     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
6792 
6793     uint64_t data = MemURead(context, address, 1, 0, &success);
6794     if (!success)
6795       return false;
6796 
6797     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6798       return false;
6799 
6800     // if wback then R[n] = offset_addr;
6801     if (wback) {
6802       context.type = eContextAdjustBaseRegister;
6803       context.SetAddress(offset_addr);
6804       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6805                                  offset_addr))
6806         return false;
6807     }
6808   }
6809   return true;
6810 }
6811 
6812 // LDRB (literal) calculates an address from the PC value and an immediate
6813 // offset, loads a byte from memory,
6814 // zero-extends it to form a 32-bit word and writes it to a register.
EmulateLDRBLiteral(const uint32_t opcode,const ARMEncoding encoding)6815 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6816                                                const ARMEncoding encoding) {
6817 #if 0
6818     if ConditionPassed() then
6819         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6820         base = Align(PC,4);
6821         address = if add then (base + imm32) else (base - imm32);
6822         R[t] = ZeroExtend(MemU[address,1], 32);
6823 #endif
6824 
6825   bool success = false;
6826 
6827   if (ConditionPassed(opcode)) {
6828     uint32_t t;
6829     uint32_t imm32;
6830     bool add;
6831     switch (encoding) {
6832     case eEncodingT1:
6833       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6834       t = Bits32(opcode, 15, 12);
6835       imm32 = Bits32(opcode, 11, 0);
6836       add = BitIsSet(opcode, 23);
6837 
6838       // if Rt == '1111' then SEE PLD;
6839       if (t == 15)
6840         return false; // PLD is not implemented yet
6841 
6842       // if t == 13 then UNPREDICTABLE;
6843       if (t == 13)
6844         return false;
6845 
6846       break;
6847 
6848     case eEncodingA1:
6849       // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6850       t = Bits32(opcode, 15, 12);
6851       imm32 = Bits32(opcode, 11, 0);
6852       add = BitIsSet(opcode, 23);
6853 
6854       // if t == 15 then UNPREDICTABLE;
6855       if (t == 15)
6856         return false;
6857       break;
6858 
6859     default:
6860       return false;
6861     }
6862 
6863     // base = Align(PC,4);
6864     uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6865     if (!success)
6866       return false;
6867 
6868     uint32_t base = AlignPC(pc_val);
6869 
6870     addr_t address;
6871     // address = if add then (base + imm32) else (base - imm32);
6872     if (add)
6873       address = base + imm32;
6874     else
6875       address = base - imm32;
6876 
6877     // R[t] = ZeroExtend(MemU[address,1], 32);
6878     EmulateInstruction::Context context;
6879     context.type = eContextRelativeBranchImmediate;
6880     context.SetImmediate(address - base);
6881 
6882     uint64_t data = MemURead(context, address, 1, 0, &success);
6883     if (!success)
6884       return false;
6885 
6886     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6887       return false;
6888   }
6889   return true;
6890 }
6891 
6892 // LDRB (register) calculates an address from a base register value and an
6893 // offset rigister value, loads a byte from memory, zero-extends it to form a
6894 // 32-bit word, and writes it to a register. The offset register value can
6895 // optionally be shifted.
EmulateLDRBRegister(const uint32_t opcode,const ARMEncoding encoding)6896 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6897                                                 const ARMEncoding encoding) {
6898 #if 0
6899     if ConditionPassed() then
6900         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6901         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6902         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6903         address = if index then offset_addr else R[n];
6904         R[t] = ZeroExtend(MemU[address,1],32);
6905         if wback then R[n] = offset_addr;
6906 #endif
6907 
6908   bool success = false;
6909 
6910   if (ConditionPassed(opcode)) {
6911     uint32_t t;
6912     uint32_t n;
6913     uint32_t m;
6914     bool index;
6915     bool add;
6916     bool wback;
6917     ARM_ShifterType shift_t;
6918     uint32_t shift_n;
6919 
6920     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6921     switch (encoding) {
6922     case eEncodingT1:
6923       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6924       t = Bits32(opcode, 2, 0);
6925       n = Bits32(opcode, 5, 3);
6926       m = Bits32(opcode, 8, 6);
6927 
6928       // index = TRUE; add = TRUE; wback = FALSE;
6929       index = true;
6930       add = true;
6931       wback = false;
6932 
6933       // (shift_t, shift_n) = (SRType_LSL, 0);
6934       shift_t = SRType_LSL;
6935       shift_n = 0;
6936       break;
6937 
6938     case eEncodingT2:
6939       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6940       t = Bits32(opcode, 15, 12);
6941       n = Bits32(opcode, 19, 16);
6942       m = Bits32(opcode, 3, 0);
6943 
6944       // index = TRUE; add = TRUE; wback = FALSE;
6945       index = true;
6946       add = true;
6947       wback = false;
6948 
6949       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6950       shift_t = SRType_LSL;
6951       shift_n = Bits32(opcode, 5, 4);
6952 
6953       // if Rt == '1111' then SEE PLD;
6954       if (t == 15)
6955         return false; // PLD is not implemented yet
6956 
6957       // if Rn == '1111' then SEE LDRB (literal);
6958       if (n == 15)
6959         return EmulateLDRBLiteral(opcode, eEncodingT1);
6960 
6961       // if t == 13 || BadReg(m) then UNPREDICTABLE;
6962       if ((t == 13) || BadReg(m))
6963         return false;
6964       break;
6965 
6966     case eEncodingA1: {
6967       // if P == '0' && W == '1' then SEE LDRBT;
6968       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6969       t = Bits32(opcode, 15, 12);
6970       n = Bits32(opcode, 19, 16);
6971       m = Bits32(opcode, 3, 0);
6972 
6973       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6974       // (W == '1');
6975       index = BitIsSet(opcode, 24);
6976       add = BitIsSet(opcode, 23);
6977       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6978 
6979       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6980       uint32_t type = Bits32(opcode, 6, 5);
6981       uint32_t imm5 = Bits32(opcode, 11, 7);
6982       shift_n = DecodeImmShift(type, imm5, shift_t);
6983 
6984       // if t == 15 || m == 15 then UNPREDICTABLE;
6985       if ((t == 15) || (m == 15))
6986         return false;
6987 
6988       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6989       if (wback && ((n == 15) || (n == t)))
6990         return false;
6991     } break;
6992 
6993     default:
6994       return false;
6995     }
6996 
6997     addr_t offset_addr;
6998     addr_t address;
6999 
7000     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7001     uint32_t Rm =
7002         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7003     if (!success)
7004       return false;
7005 
7006     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7007     if (!success)
7008       return false;
7009 
7010     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7011     uint32_t Rn =
7012         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7013     if (!success)
7014       return false;
7015 
7016     if (add)
7017       offset_addr = Rn + offset;
7018     else
7019       offset_addr = Rn - offset;
7020 
7021     // address = if index then offset_addr else R[n];
7022     if (index)
7023       address = offset_addr;
7024     else
7025       address = Rn;
7026 
7027     // R[t] = ZeroExtend(MemU[address,1],32);
7028     std::optional<RegisterInfo> base_reg =
7029         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7030 
7031     EmulateInstruction::Context context;
7032     context.type = eContextRegisterLoad;
7033     context.SetRegisterPlusOffset(*base_reg, address - Rn);
7034 
7035     uint64_t data = MemURead(context, address, 1, 0, &success);
7036     if (!success)
7037       return false;
7038 
7039     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7040       return false;
7041 
7042     // if wback then R[n] = offset_addr;
7043     if (wback) {
7044       context.type = eContextAdjustBaseRegister;
7045       context.SetAddress(offset_addr);
7046       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7047                                  offset_addr))
7048         return false;
7049     }
7050   }
7051   return true;
7052 }
7053 
7054 // LDRH (immediate, Thumb) calculates an address from a base register value and
7055 // an immediate offset, loads a
7056 // halfword from memory, zero-extends it to form a 32-bit word, and writes it
7057 // to a register.  It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRHImmediate(const uint32_t opcode,const ARMEncoding encoding)7058 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7059                                                  const ARMEncoding encoding) {
7060 #if 0
7061     if ConditionPassed() then
7062         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7063         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7064         address = if index then offset_addr else R[n];
7065         data = MemU[address,2];
7066         if wback then R[n] = offset_addr;
7067         if UnalignedSupport() || address<0> = '0' then
7068             R[t] = ZeroExtend(data, 32);
7069         else // Can only apply before ARMv7
7070             R[t] = bits(32) UNKNOWN;
7071 #endif
7072 
7073   bool success = false;
7074 
7075   if (ConditionPassed(opcode)) {
7076     uint32_t t;
7077     uint32_t n;
7078     uint32_t imm32;
7079     bool index;
7080     bool add;
7081     bool wback;
7082 
7083     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7084     switch (encoding) {
7085     case eEncodingT1:
7086       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7087       t = Bits32(opcode, 2, 0);
7088       n = Bits32(opcode, 5, 3);
7089       imm32 = Bits32(opcode, 10, 6) << 1;
7090 
7091       // index = TRUE; add = TRUE; wback = FALSE;
7092       index = true;
7093       add = true;
7094       wback = false;
7095 
7096       break;
7097 
7098     case eEncodingT2:
7099       // if Rt == '1111' then SEE "Unallocated memory hints";
7100       // if Rn == '1111' then SEE LDRH (literal);
7101       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7102       t = Bits32(opcode, 15, 12);
7103       n = Bits32(opcode, 19, 16);
7104       imm32 = Bits32(opcode, 11, 0);
7105 
7106       // index = TRUE; add = TRUE; wback = FALSE;
7107       index = true;
7108       add = true;
7109       wback = false;
7110 
7111       // if t == 13 then UNPREDICTABLE;
7112       if (t == 13)
7113         return false;
7114       break;
7115 
7116     case eEncodingT3:
7117       // if Rn == '1111' then SEE LDRH (literal);
7118       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7119       // "Unallocated memory hints";
7120       // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7121       // if P == '0' && W == '0' then UNDEFINED;
7122       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7123         return false;
7124 
7125       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7126       t = Bits32(opcode, 15, 12);
7127       n = Bits32(opcode, 19, 16);
7128       imm32 = Bits32(opcode, 7, 0);
7129 
7130       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7131       index = BitIsSet(opcode, 10);
7132       add = BitIsSet(opcode, 9);
7133       wback = BitIsSet(opcode, 8);
7134 
7135       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7136       if (BadReg(t) || (wback && (n == t)))
7137         return false;
7138       break;
7139 
7140     default:
7141       return false;
7142     }
7143 
7144     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7145     uint32_t Rn =
7146         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7147     if (!success)
7148       return false;
7149 
7150     addr_t offset_addr;
7151     addr_t address;
7152 
7153     if (add)
7154       offset_addr = Rn + imm32;
7155     else
7156       offset_addr = Rn - imm32;
7157 
7158     // address = if index then offset_addr else R[n];
7159     if (index)
7160       address = offset_addr;
7161     else
7162       address = Rn;
7163 
7164     // data = MemU[address,2];
7165     std::optional<RegisterInfo> base_reg =
7166         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7167 
7168     EmulateInstruction::Context context;
7169     context.type = eContextRegisterLoad;
7170     context.SetRegisterPlusOffset(*base_reg, address - Rn);
7171 
7172     uint64_t data = MemURead(context, address, 2, 0, &success);
7173     if (!success)
7174       return false;
7175 
7176     // if wback then R[n] = offset_addr;
7177     if (wback) {
7178       context.type = eContextAdjustBaseRegister;
7179       context.SetAddress(offset_addr);
7180       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7181                                  offset_addr))
7182         return false;
7183     }
7184 
7185     // if UnalignedSupport() || address<0> = '0' then
7186     if (UnalignedSupport() || BitIsClear(address, 0)) {
7187       // R[t] = ZeroExtend(data, 32);
7188       context.type = eContextRegisterLoad;
7189       context.SetRegisterPlusOffset(*base_reg, address - Rn);
7190       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7191                                  data))
7192         return false;
7193     } else // Can only apply before ARMv7
7194     {
7195       // R[t] = bits(32) UNKNOWN;
7196       WriteBits32Unknown(t);
7197     }
7198   }
7199   return true;
7200 }
7201 
7202 // LDRH (literal) calculates an address from the PC value and an immediate
7203 // offset, loads a halfword from memory,
7204 // zero-extends it to form a 32-bit word, and writes it to a register.
EmulateLDRHLiteral(const uint32_t opcode,const ARMEncoding encoding)7205 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7206                                                const ARMEncoding encoding) {
7207 #if 0
7208     if ConditionPassed() then
7209         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7210         base = Align(PC,4);
7211         address = if add then (base + imm32) else (base - imm32);
7212         data = MemU[address,2];
7213         if UnalignedSupport() || address<0> = '0' then
7214             R[t] = ZeroExtend(data, 32);
7215         else // Can only apply before ARMv7
7216             R[t] = bits(32) UNKNOWN;
7217 #endif
7218 
7219   bool success = false;
7220 
7221   if (ConditionPassed(opcode)) {
7222     uint32_t t;
7223     uint32_t imm32;
7224     bool add;
7225 
7226     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7227     switch (encoding) {
7228     case eEncodingT1:
7229       // if Rt == '1111' then SEE "Unallocated memory hints";
7230       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7231       t = Bits32(opcode, 15, 12);
7232       imm32 = Bits32(opcode, 11, 0);
7233       add = BitIsSet(opcode, 23);
7234 
7235       // if t == 13 then UNPREDICTABLE;
7236       if (t == 13)
7237         return false;
7238 
7239       break;
7240 
7241     case eEncodingA1: {
7242       uint32_t imm4H = Bits32(opcode, 11, 8);
7243       uint32_t imm4L = Bits32(opcode, 3, 0);
7244 
7245       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7246       t = Bits32(opcode, 15, 12);
7247       imm32 = (imm4H << 4) | imm4L;
7248       add = BitIsSet(opcode, 23);
7249 
7250       // if t == 15 then UNPREDICTABLE;
7251       if (t == 15)
7252         return false;
7253       break;
7254     }
7255 
7256     default:
7257       return false;
7258     }
7259 
7260     // base = Align(PC,4);
7261     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7262     if (!success)
7263       return false;
7264 
7265     addr_t base = AlignPC(pc_value);
7266     addr_t address;
7267 
7268     // address = if add then (base + imm32) else (base - imm32);
7269     if (add)
7270       address = base + imm32;
7271     else
7272       address = base - imm32;
7273 
7274     // data = MemU[address,2];
7275     std::optional<RegisterInfo> base_reg =
7276         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7277 
7278     EmulateInstruction::Context context;
7279     context.type = eContextRegisterLoad;
7280     context.SetRegisterPlusOffset(*base_reg, address - base);
7281 
7282     uint64_t data = MemURead(context, address, 2, 0, &success);
7283     if (!success)
7284       return false;
7285 
7286     // if UnalignedSupport() || address<0> = '0' then
7287     if (UnalignedSupport() || BitIsClear(address, 0)) {
7288       // R[t] = ZeroExtend(data, 32);
7289       context.type = eContextRegisterLoad;
7290       context.SetRegisterPlusOffset(*base_reg, address - base);
7291       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7292                                  data))
7293         return false;
7294 
7295     } else // Can only apply before ARMv7
7296     {
7297       // R[t] = bits(32) UNKNOWN;
7298       WriteBits32Unknown(t);
7299     }
7300   }
7301   return true;
7302 }
7303 
7304 // LDRH (literal) calculates an address from a base register value and an offset
7305 // register value, loads a halfword
7306 // from memory, zero-extends it to form a 32-bit word, and writes it to a
7307 // register.  The offset register value can be shifted left by 0, 1, 2, or 3
7308 // bits.
EmulateLDRHRegister(const uint32_t opcode,const ARMEncoding encoding)7309 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7310                                                 const ARMEncoding encoding) {
7311 #if 0
7312     if ConditionPassed() then
7313         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7314         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7315         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7316         address = if index then offset_addr else R[n];
7317         data = MemU[address,2];
7318         if wback then R[n] = offset_addr;
7319         if UnalignedSupport() || address<0> = '0' then
7320             R[t] = ZeroExtend(data, 32);
7321         else // Can only apply before ARMv7
7322             R[t] = bits(32) UNKNOWN;
7323 #endif
7324 
7325   bool success = false;
7326 
7327   if (ConditionPassed(opcode)) {
7328     uint32_t t;
7329     uint32_t n;
7330     uint32_t m;
7331     bool index;
7332     bool add;
7333     bool wback;
7334     ARM_ShifterType shift_t;
7335     uint32_t shift_n;
7336 
7337     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7338     switch (encoding) {
7339     case eEncodingT1:
7340       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7341       // in ThumbEE";
7342       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7343       t = Bits32(opcode, 2, 0);
7344       n = Bits32(opcode, 5, 3);
7345       m = Bits32(opcode, 8, 6);
7346 
7347       // index = TRUE; add = TRUE; wback = FALSE;
7348       index = true;
7349       add = true;
7350       wback = false;
7351 
7352       // (shift_t, shift_n) = (SRType_LSL, 0);
7353       shift_t = SRType_LSL;
7354       shift_n = 0;
7355 
7356       break;
7357 
7358     case eEncodingT2:
7359       // if Rn == '1111' then SEE LDRH (literal);
7360       // if Rt == '1111' then SEE "Unallocated memory hints";
7361       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7362       t = Bits32(opcode, 15, 12);
7363       n = Bits32(opcode, 19, 16);
7364       m = Bits32(opcode, 3, 0);
7365 
7366       // index = TRUE; add = TRUE; wback = FALSE;
7367       index = true;
7368       add = true;
7369       wback = false;
7370 
7371       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7372       shift_t = SRType_LSL;
7373       shift_n = Bits32(opcode, 5, 4);
7374 
7375       // if t == 13 || BadReg(m) then UNPREDICTABLE;
7376       if ((t == 13) || BadReg(m))
7377         return false;
7378       break;
7379 
7380     case eEncodingA1:
7381       // if P == '0' && W == '1' then SEE LDRHT;
7382       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7383       t = Bits32(opcode, 15, 12);
7384       n = Bits32(opcode, 19, 16);
7385       m = Bits32(opcode, 3, 0);
7386 
7387       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7388       // (W == '1');
7389       index = BitIsSet(opcode, 24);
7390       add = BitIsSet(opcode, 23);
7391       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7392 
7393       // (shift_t, shift_n) = (SRType_LSL, 0);
7394       shift_t = SRType_LSL;
7395       shift_n = 0;
7396 
7397       // if t == 15 || m == 15 then UNPREDICTABLE;
7398       if ((t == 15) || (m == 15))
7399         return false;
7400 
7401       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7402       if (wback && ((n == 15) || (n == t)))
7403         return false;
7404 
7405       break;
7406 
7407     default:
7408       return false;
7409     }
7410 
7411     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7412 
7413     uint64_t Rm =
7414         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7415     if (!success)
7416       return false;
7417 
7418     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7419     if (!success)
7420       return false;
7421 
7422     addr_t offset_addr;
7423     addr_t address;
7424 
7425     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7426     uint64_t Rn =
7427         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7428     if (!success)
7429       return false;
7430 
7431     if (add)
7432       offset_addr = Rn + offset;
7433     else
7434       offset_addr = Rn - offset;
7435 
7436     // address = if index then offset_addr else R[n];
7437     if (index)
7438       address = offset_addr;
7439     else
7440       address = Rn;
7441 
7442     // data = MemU[address,2];
7443     std::optional<RegisterInfo> base_reg =
7444         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7445     std::optional<RegisterInfo> offset_reg =
7446         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
7447 
7448     EmulateInstruction::Context context;
7449     context.type = eContextRegisterLoad;
7450     context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7451     uint64_t data = MemURead(context, address, 2, 0, &success);
7452     if (!success)
7453       return false;
7454 
7455     // if wback then R[n] = offset_addr;
7456     if (wback) {
7457       context.type = eContextAdjustBaseRegister;
7458       context.SetAddress(offset_addr);
7459       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7460                                  offset_addr))
7461         return false;
7462     }
7463 
7464     // if UnalignedSupport() || address<0> = '0' then
7465     if (UnalignedSupport() || BitIsClear(address, 0)) {
7466       // R[t] = ZeroExtend(data, 32);
7467       context.type = eContextRegisterLoad;
7468       context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7469       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7470                                  data))
7471         return false;
7472     } else // Can only apply before ARMv7
7473     {
7474       // R[t] = bits(32) UNKNOWN;
7475       WriteBits32Unknown(t);
7476     }
7477   }
7478   return true;
7479 }
7480 
7481 // LDRSB (immediate) calculates an address from a base register value and an
7482 // immediate offset, loads a byte from
7483 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7484 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSBImmediate(const uint32_t opcode,const ARMEncoding encoding)7485 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7486                                                   const ARMEncoding encoding) {
7487 #if 0
7488     if ConditionPassed() then
7489         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7490         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7491         address = if index then offset_addr else R[n];
7492         R[t] = SignExtend(MemU[address,1], 32);
7493         if wback then R[n] = offset_addr;
7494 #endif
7495 
7496   bool success = false;
7497 
7498   if (ConditionPassed(opcode)) {
7499     uint32_t t;
7500     uint32_t n;
7501     uint32_t imm32;
7502     bool index;
7503     bool add;
7504     bool wback;
7505 
7506     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7507     switch (encoding) {
7508     case eEncodingT1:
7509       // if Rt == '1111' then SEE PLI;
7510       // if Rn == '1111' then SEE LDRSB (literal);
7511       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7512       t = Bits32(opcode, 15, 12);
7513       n = Bits32(opcode, 19, 16);
7514       imm32 = Bits32(opcode, 11, 0);
7515 
7516       // index = TRUE; add = TRUE; wback = FALSE;
7517       index = true;
7518       add = true;
7519       wback = false;
7520 
7521       // if t == 13 then UNPREDICTABLE;
7522       if (t == 13)
7523         return false;
7524 
7525       break;
7526 
7527     case eEncodingT2:
7528       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7529       // if Rn == '1111' then SEE LDRSB (literal);
7530       // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7531       // if P == '0' && W == '0' then UNDEFINED;
7532       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7533         return false;
7534 
7535       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7536       t = Bits32(opcode, 15, 12);
7537       n = Bits32(opcode, 19, 16);
7538       imm32 = Bits32(opcode, 7, 0);
7539 
7540       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7541       index = BitIsSet(opcode, 10);
7542       add = BitIsSet(opcode, 9);
7543       wback = BitIsSet(opcode, 8);
7544 
7545       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7546       if (((t == 13) ||
7547            ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7548                           BitIsSet(opcode, 8)))) ||
7549           (wback && (n == t)))
7550         return false;
7551 
7552       break;
7553 
7554     case eEncodingA1: {
7555       // if Rn == '1111' then SEE LDRSB (literal);
7556       // if P == '0' && W == '1' then SEE LDRSBT;
7557       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7558       t = Bits32(opcode, 15, 12);
7559       n = Bits32(opcode, 19, 16);
7560 
7561       uint32_t imm4H = Bits32(opcode, 11, 8);
7562       uint32_t imm4L = Bits32(opcode, 3, 0);
7563       imm32 = (imm4H << 4) | imm4L;
7564 
7565       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7566       // (W == '1');
7567       index = BitIsSet(opcode, 24);
7568       add = BitIsSet(opcode, 23);
7569       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7570 
7571       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7572       if ((t == 15) || (wback && (n == t)))
7573         return false;
7574 
7575       break;
7576     }
7577 
7578     default:
7579       return false;
7580     }
7581 
7582     uint64_t Rn = ReadCoreReg(n, &success);
7583     if (!success)
7584       return false;
7585 
7586     addr_t offset_addr;
7587     addr_t address;
7588 
7589     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7590     if (add)
7591       offset_addr = Rn + imm32;
7592     else
7593       offset_addr = Rn - imm32;
7594 
7595     // address = if index then offset_addr else R[n];
7596     if (index)
7597       address = offset_addr;
7598     else
7599       address = Rn;
7600 
7601     // R[t] = SignExtend(MemU[address,1], 32);
7602     std::optional<RegisterInfo> base_reg =
7603         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7604 
7605     EmulateInstruction::Context context;
7606     context.type = eContextRegisterLoad;
7607     context.SetRegisterPlusOffset(*base_reg, address - Rn);
7608 
7609     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7610     if (!success)
7611       return false;
7612 
7613     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7614     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7615                                (uint64_t)signed_data))
7616       return false;
7617 
7618     // if wback then R[n] = offset_addr;
7619     if (wback) {
7620       context.type = eContextAdjustBaseRegister;
7621       context.SetAddress(offset_addr);
7622       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7623                                  offset_addr))
7624         return false;
7625     }
7626   }
7627 
7628   return true;
7629 }
7630 
7631 // LDRSB (literal) calculates an address from the PC value and an immediate
7632 // offset, loads a byte from memory,
7633 // sign-extends it to form a 32-bit word, and writes tit to a register.
EmulateLDRSBLiteral(const uint32_t opcode,const ARMEncoding encoding)7634 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7635                                                 const ARMEncoding encoding) {
7636 #if 0
7637     if ConditionPassed() then
7638         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7639         base = Align(PC,4);
7640         address = if add then (base + imm32) else (base - imm32);
7641         R[t] = SignExtend(MemU[address,1], 32);
7642 #endif
7643 
7644   bool success = false;
7645 
7646   if (ConditionPassed(opcode)) {
7647     uint32_t t;
7648     uint32_t imm32;
7649     bool add;
7650 
7651     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7652     switch (encoding) {
7653     case eEncodingT1:
7654       // if Rt == '1111' then SEE PLI;
7655       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7656       t = Bits32(opcode, 15, 12);
7657       imm32 = Bits32(opcode, 11, 0);
7658       add = BitIsSet(opcode, 23);
7659 
7660       // if t == 13 then UNPREDICTABLE;
7661       if (t == 13)
7662         return false;
7663 
7664       break;
7665 
7666     case eEncodingA1: {
7667       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7668       t = Bits32(opcode, 15, 12);
7669       uint32_t imm4H = Bits32(opcode, 11, 8);
7670       uint32_t imm4L = Bits32(opcode, 3, 0);
7671       imm32 = (imm4H << 4) | imm4L;
7672       add = BitIsSet(opcode, 23);
7673 
7674       // if t == 15 then UNPREDICTABLE;
7675       if (t == 15)
7676         return false;
7677 
7678       break;
7679     }
7680 
7681     default:
7682       return false;
7683     }
7684 
7685     // base = Align(PC,4);
7686     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7687     if (!success)
7688       return false;
7689     uint64_t base = AlignPC(pc_value);
7690 
7691     // address = if add then (base + imm32) else (base - imm32);
7692     addr_t address;
7693     if (add)
7694       address = base + imm32;
7695     else
7696       address = base - imm32;
7697 
7698     // R[t] = SignExtend(MemU[address,1], 32);
7699     std::optional<RegisterInfo> base_reg =
7700         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7701 
7702     EmulateInstruction::Context context;
7703     context.type = eContextRegisterLoad;
7704     context.SetRegisterPlusOffset(*base_reg, address - base);
7705 
7706     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7707     if (!success)
7708       return false;
7709 
7710     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7711     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7712                                (uint64_t)signed_data))
7713       return false;
7714   }
7715   return true;
7716 }
7717 
7718 // LDRSB (register) calculates an address from a base register value and an
7719 // offset register value, loadsa byte from
7720 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7721 // The offset register value can be shifted left by 0, 1, 2, or 3 bits.
EmulateLDRSBRegister(const uint32_t opcode,const ARMEncoding encoding)7722 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7723                                                  const ARMEncoding encoding) {
7724 #if 0
7725     if ConditionPassed() then
7726         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7727         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7728         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7729         address = if index then offset_addr else R[n];
7730         R[t] = SignExtend(MemU[address,1], 32);
7731         if wback then R[n] = offset_addr;
7732 #endif
7733 
7734   bool success = false;
7735 
7736   if (ConditionPassed(opcode)) {
7737     uint32_t t;
7738     uint32_t n;
7739     uint32_t m;
7740     bool index;
7741     bool add;
7742     bool wback;
7743     ARM_ShifterType shift_t;
7744     uint32_t shift_n;
7745 
7746     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7747     switch (encoding) {
7748     case eEncodingT1:
7749       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7750       t = Bits32(opcode, 2, 0);
7751       n = Bits32(opcode, 5, 3);
7752       m = Bits32(opcode, 8, 6);
7753 
7754       // index = TRUE; add = TRUE; wback = FALSE;
7755       index = true;
7756       add = true;
7757       wback = false;
7758 
7759       // (shift_t, shift_n) = (SRType_LSL, 0);
7760       shift_t = SRType_LSL;
7761       shift_n = 0;
7762 
7763       break;
7764 
7765     case eEncodingT2:
7766       // if Rt == '1111' then SEE PLI;
7767       // if Rn == '1111' then SEE LDRSB (literal);
7768       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7769       t = Bits32(opcode, 15, 12);
7770       n = Bits32(opcode, 19, 16);
7771       m = Bits32(opcode, 3, 0);
7772 
7773       // index = TRUE; add = TRUE; wback = FALSE;
7774       index = true;
7775       add = true;
7776       wback = false;
7777 
7778       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7779       shift_t = SRType_LSL;
7780       shift_n = Bits32(opcode, 5, 4);
7781 
7782       // if t == 13 || BadReg(m) then UNPREDICTABLE;
7783       if ((t == 13) || BadReg(m))
7784         return false;
7785       break;
7786 
7787     case eEncodingA1:
7788       // if P == '0' && W == '1' then SEE LDRSBT;
7789       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7790       t = Bits32(opcode, 15, 12);
7791       n = Bits32(opcode, 19, 16);
7792       m = Bits32(opcode, 3, 0);
7793 
7794       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7795       // (W == '1');
7796       index = BitIsSet(opcode, 24);
7797       add = BitIsSet(opcode, 23);
7798       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7799 
7800       // (shift_t, shift_n) = (SRType_LSL, 0);
7801       shift_t = SRType_LSL;
7802       shift_n = 0;
7803 
7804       // if t == 15 || m == 15 then UNPREDICTABLE;
7805       if ((t == 15) || (m == 15))
7806         return false;
7807 
7808       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7809       if (wback && ((n == 15) || (n == t)))
7810         return false;
7811       break;
7812 
7813     default:
7814       return false;
7815     }
7816 
7817     uint64_t Rm =
7818         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7819     if (!success)
7820       return false;
7821 
7822     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7823     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7824     if (!success)
7825       return false;
7826 
7827     addr_t offset_addr;
7828     addr_t address;
7829 
7830     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7831     uint64_t Rn =
7832         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7833     if (!success)
7834       return false;
7835 
7836     if (add)
7837       offset_addr = Rn + offset;
7838     else
7839       offset_addr = Rn - offset;
7840 
7841     // address = if index then offset_addr else R[n];
7842     if (index)
7843       address = offset_addr;
7844     else
7845       address = Rn;
7846 
7847     // R[t] = SignExtend(MemU[address,1], 32);
7848     std::optional<RegisterInfo> base_reg =
7849         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
7850     std::optional<RegisterInfo> offset_reg =
7851         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
7852 
7853     EmulateInstruction::Context context;
7854     context.type = eContextRegisterLoad;
7855     context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
7856 
7857     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7858     if (!success)
7859       return false;
7860 
7861     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7862     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7863                                (uint64_t)signed_data))
7864       return false;
7865 
7866     // if wback then R[n] = offset_addr;
7867     if (wback) {
7868       context.type = eContextAdjustBaseRegister;
7869       context.SetAddress(offset_addr);
7870       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7871                                  offset_addr))
7872         return false;
7873     }
7874   }
7875   return true;
7876 }
7877 
7878 // LDRSH (immediate) calculates an address from a base register value and an
7879 // immediate offset, loads a halfword from
7880 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7881 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSHImmediate(const uint32_t opcode,const ARMEncoding encoding)7882 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7883                                                   const ARMEncoding encoding) {
7884 #if 0
7885     if ConditionPassed() then
7886         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7887         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7888         address = if index then offset_addr else R[n];
7889         data = MemU[address,2];
7890         if wback then R[n] = offset_addr;
7891         if UnalignedSupport() || address<0> = '0' then
7892             R[t] = SignExtend(data, 32);
7893         else // Can only apply before ARMv7
7894             R[t] = bits(32) UNKNOWN;
7895 #endif
7896 
7897   bool success = false;
7898 
7899   if (ConditionPassed(opcode)) {
7900     uint32_t t;
7901     uint32_t n;
7902     uint32_t imm32;
7903     bool index;
7904     bool add;
7905     bool wback;
7906 
7907     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7908     switch (encoding) {
7909     case eEncodingT1:
7910       // if Rn == '1111' then SEE LDRSH (literal);
7911       // if Rt == '1111' then SEE "Unallocated memory hints";
7912       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7913       t = Bits32(opcode, 15, 12);
7914       n = Bits32(opcode, 19, 16);
7915       imm32 = Bits32(opcode, 11, 0);
7916 
7917       // index = TRUE; add = TRUE; wback = FALSE;
7918       index = true;
7919       add = true;
7920       wback = false;
7921 
7922       // if t == 13 then UNPREDICTABLE;
7923       if (t == 13)
7924         return false;
7925 
7926       break;
7927 
7928     case eEncodingT2:
7929       // if Rn == '1111' then SEE LDRSH (literal);
7930       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7931       // "Unallocated memory hints";
7932       // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7933       // if P == '0' && W == '0' then UNDEFINED;
7934       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7935         return false;
7936 
7937       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7938       t = Bits32(opcode, 15, 12);
7939       n = Bits32(opcode, 19, 16);
7940       imm32 = Bits32(opcode, 7, 0);
7941 
7942       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7943       index = BitIsSet(opcode, 10);
7944       add = BitIsSet(opcode, 9);
7945       wback = BitIsSet(opcode, 8);
7946 
7947       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7948       if (BadReg(t) || (wback && (n == t)))
7949         return false;
7950 
7951       break;
7952 
7953     case eEncodingA1: {
7954       // if Rn == '1111' then SEE LDRSH (literal);
7955       // if P == '0' && W == '1' then SEE LDRSHT;
7956       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7957       t = Bits32(opcode, 15, 12);
7958       n = Bits32(opcode, 19, 16);
7959       uint32_t imm4H = Bits32(opcode, 11, 8);
7960       uint32_t imm4L = Bits32(opcode, 3, 0);
7961       imm32 = (imm4H << 4) | imm4L;
7962 
7963       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7964       // (W == '1');
7965       index = BitIsSet(opcode, 24);
7966       add = BitIsSet(opcode, 23);
7967       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7968 
7969       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7970       if ((t == 15) || (wback && (n == t)))
7971         return false;
7972 
7973       break;
7974     }
7975 
7976     default:
7977       return false;
7978     }
7979 
7980     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7981     uint64_t Rn =
7982         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7983     if (!success)
7984       return false;
7985 
7986     addr_t offset_addr;
7987     if (add)
7988       offset_addr = Rn + imm32;
7989     else
7990       offset_addr = Rn - imm32;
7991 
7992     // address = if index then offset_addr else R[n];
7993     addr_t address;
7994     if (index)
7995       address = offset_addr;
7996     else
7997       address = Rn;
7998 
7999     // data = MemU[address,2];
8000     std::optional<RegisterInfo> base_reg =
8001         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8002 
8003     EmulateInstruction::Context context;
8004     context.type = eContextRegisterLoad;
8005     context.SetRegisterPlusOffset(*base_reg, address - Rn);
8006 
8007     uint64_t data = MemURead(context, address, 2, 0, &success);
8008     if (!success)
8009       return false;
8010 
8011     // if wback then R[n] = offset_addr;
8012     if (wback) {
8013       context.type = eContextAdjustBaseRegister;
8014       context.SetAddress(offset_addr);
8015       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8016                                  offset_addr))
8017         return false;
8018     }
8019 
8020     // if UnalignedSupport() || address<0> = '0' then
8021     if (UnalignedSupport() || BitIsClear(address, 0)) {
8022       // R[t] = SignExtend(data, 32);
8023       int64_t signed_data = llvm::SignExtend64<16>(data);
8024       context.type = eContextRegisterLoad;
8025       context.SetRegisterPlusOffset(*base_reg, address - Rn);
8026       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8027                                  (uint64_t)signed_data))
8028         return false;
8029     } else // Can only apply before ARMv7
8030     {
8031       // R[t] = bits(32) UNKNOWN;
8032       WriteBits32Unknown(t);
8033     }
8034   }
8035   return true;
8036 }
8037 
8038 // LDRSH (literal) calculates an address from the PC value and an immediate
8039 // offset, loads a halfword from memory,
8040 // sign-extends it to from a 32-bit word, and writes it to a register.
EmulateLDRSHLiteral(const uint32_t opcode,const ARMEncoding encoding)8041 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8042                                                 const ARMEncoding encoding) {
8043 #if 0
8044     if ConditionPassed() then
8045         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8046         base = Align(PC,4);
8047         address = if add then (base + imm32) else (base - imm32);
8048         data = MemU[address,2];
8049         if UnalignedSupport() || address<0> = '0' then
8050             R[t] = SignExtend(data, 32);
8051         else // Can only apply before ARMv7
8052             R[t] = bits(32) UNKNOWN;
8053 #endif
8054 
8055   bool success = false;
8056 
8057   if (ConditionPassed(opcode)) {
8058     uint32_t t;
8059     uint32_t imm32;
8060     bool add;
8061 
8062     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8063     switch (encoding) {
8064     case eEncodingT1:
8065       // if Rt == '1111' then SEE "Unallocated memory hints";
8066       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8067       t = Bits32(opcode, 15, 12);
8068       imm32 = Bits32(opcode, 11, 0);
8069       add = BitIsSet(opcode, 23);
8070 
8071       // if t == 13 then UNPREDICTABLE;
8072       if (t == 13)
8073         return false;
8074 
8075       break;
8076 
8077     case eEncodingA1: {
8078       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8079       t = Bits32(opcode, 15, 12);
8080       uint32_t imm4H = Bits32(opcode, 11, 8);
8081       uint32_t imm4L = Bits32(opcode, 3, 0);
8082       imm32 = (imm4H << 4) | imm4L;
8083       add = BitIsSet(opcode, 23);
8084 
8085       // if t == 15 then UNPREDICTABLE;
8086       if (t == 15)
8087         return false;
8088 
8089       break;
8090     }
8091     default:
8092       return false;
8093     }
8094 
8095     // base = Align(PC,4);
8096     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8097     if (!success)
8098       return false;
8099 
8100     uint64_t base = AlignPC(pc_value);
8101 
8102     addr_t address;
8103     // address = if add then (base + imm32) else (base - imm32);
8104     if (add)
8105       address = base + imm32;
8106     else
8107       address = base - imm32;
8108 
8109     // data = MemU[address,2];
8110     std::optional<RegisterInfo> base_reg =
8111         GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
8112 
8113     EmulateInstruction::Context context;
8114     context.type = eContextRegisterLoad;
8115     context.SetRegisterPlusOffset(*base_reg, imm32);
8116 
8117     uint64_t data = MemURead(context, address, 2, 0, &success);
8118     if (!success)
8119       return false;
8120 
8121     // if UnalignedSupport() || address<0> = '0' then
8122     if (UnalignedSupport() || BitIsClear(address, 0)) {
8123       // R[t] = SignExtend(data, 32);
8124       int64_t signed_data = llvm::SignExtend64<16>(data);
8125       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8126                                  (uint64_t)signed_data))
8127         return false;
8128     } else // Can only apply before ARMv7
8129     {
8130       // R[t] = bits(32) UNKNOWN;
8131       WriteBits32Unknown(t);
8132     }
8133   }
8134   return true;
8135 }
8136 
8137 // LDRSH (register) calculates an address from a base register value and an
8138 // offset register value, loads a halfword
8139 // from memory, sign-extends it to form a 32-bit word, and writes it to a
8140 // register.  The offset register value can be shifted left by 0, 1, 2, or 3
8141 // bits.
EmulateLDRSHRegister(const uint32_t opcode,const ARMEncoding encoding)8142 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8143                                                  const ARMEncoding encoding) {
8144 #if 0
8145     if ConditionPassed() then
8146         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8147         offset = Shift(R[m], shift_t, shift_n, APSR.C);
8148         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8149         address = if index then offset_addr else R[n];
8150         data = MemU[address,2];
8151         if wback then R[n] = offset_addr;
8152         if UnalignedSupport() || address<0> = '0' then
8153             R[t] = SignExtend(data, 32);
8154         else // Can only apply before ARMv7
8155             R[t] = bits(32) UNKNOWN;
8156 #endif
8157 
8158   bool success = false;
8159 
8160   if (ConditionPassed(opcode)) {
8161     uint32_t t;
8162     uint32_t n;
8163     uint32_t m;
8164     bool index;
8165     bool add;
8166     bool wback;
8167     ARM_ShifterType shift_t;
8168     uint32_t shift_n;
8169 
8170     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8171     switch (encoding) {
8172     case eEncodingT1:
8173       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8174       // in ThumbEE";
8175       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8176       t = Bits32(opcode, 2, 0);
8177       n = Bits32(opcode, 5, 3);
8178       m = Bits32(opcode, 8, 6);
8179 
8180       // index = TRUE; add = TRUE; wback = FALSE;
8181       index = true;
8182       add = true;
8183       wback = false;
8184 
8185       // (shift_t, shift_n) = (SRType_LSL, 0);
8186       shift_t = SRType_LSL;
8187       shift_n = 0;
8188 
8189       break;
8190 
8191     case eEncodingT2:
8192       // if Rn == '1111' then SEE LDRSH (literal);
8193       // if Rt == '1111' then SEE "Unallocated memory hints";
8194       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8195       t = Bits32(opcode, 15, 12);
8196       n = Bits32(opcode, 19, 16);
8197       m = Bits32(opcode, 3, 0);
8198 
8199       // index = TRUE; add = TRUE; wback = FALSE;
8200       index = true;
8201       add = true;
8202       wback = false;
8203 
8204       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8205       shift_t = SRType_LSL;
8206       shift_n = Bits32(opcode, 5, 4);
8207 
8208       // if t == 13 || BadReg(m) then UNPREDICTABLE;
8209       if ((t == 13) || BadReg(m))
8210         return false;
8211 
8212       break;
8213 
8214     case eEncodingA1:
8215       // if P == '0' && W == '1' then SEE LDRSHT;
8216       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8217       t = Bits32(opcode, 15, 12);
8218       n = Bits32(opcode, 19, 16);
8219       m = Bits32(opcode, 3, 0);
8220 
8221       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
8222       // (W == '1');
8223       index = BitIsSet(opcode, 24);
8224       add = BitIsSet(opcode, 23);
8225       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8226 
8227       // (shift_t, shift_n) = (SRType_LSL, 0);
8228       shift_t = SRType_LSL;
8229       shift_n = 0;
8230 
8231       // if t == 15 || m == 15 then UNPREDICTABLE;
8232       if ((t == 15) || (m == 15))
8233         return false;
8234 
8235       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8236       if (wback && ((n == 15) || (n == t)))
8237         return false;
8238 
8239       break;
8240 
8241     default:
8242       return false;
8243     }
8244 
8245     uint64_t Rm =
8246         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8247     if (!success)
8248       return false;
8249 
8250     uint64_t Rn =
8251         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8252     if (!success)
8253       return false;
8254 
8255     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8256     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8257     if (!success)
8258       return false;
8259 
8260     addr_t offset_addr;
8261     addr_t address;
8262 
8263     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8264     if (add)
8265       offset_addr = Rn + offset;
8266     else
8267       offset_addr = Rn - offset;
8268 
8269     // address = if index then offset_addr else R[n];
8270     if (index)
8271       address = offset_addr;
8272     else
8273       address = Rn;
8274 
8275     // data = MemU[address,2];
8276     std::optional<RegisterInfo> base_reg =
8277         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8278     std::optional<RegisterInfo> offset_reg =
8279         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8280 
8281     EmulateInstruction::Context context;
8282     context.type = eContextRegisterLoad;
8283     context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
8284 
8285     uint64_t data = MemURead(context, address, 2, 0, &success);
8286     if (!success)
8287       return false;
8288 
8289     // if wback then R[n] = offset_addr;
8290     if (wback) {
8291       context.type = eContextAdjustBaseRegister;
8292       context.SetAddress(offset_addr);
8293       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8294                                  offset_addr))
8295         return false;
8296     }
8297 
8298     // if UnalignedSupport() || address<0> = '0' then
8299     if (UnalignedSupport() || BitIsClear(address, 0)) {
8300       // R[t] = SignExtend(data, 32);
8301       context.type = eContextRegisterLoad;
8302       context.SetRegisterPlusIndirectOffset(*base_reg, *offset_reg);
8303 
8304       int64_t signed_data = llvm::SignExtend64<16>(data);
8305       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8306                                  (uint64_t)signed_data))
8307         return false;
8308     } else // Can only apply before ARMv7
8309     {
8310       // R[t] = bits(32) UNKNOWN;
8311       WriteBits32Unknown(t);
8312     }
8313   }
8314   return true;
8315 }
8316 
8317 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8318 // writes the result to the destination
8319 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8320 // extracting the 8-bit value.
EmulateSXTB(const uint32_t opcode,const ARMEncoding encoding)8321 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8322                                         const ARMEncoding encoding) {
8323 #if 0
8324     if ConditionPassed() then
8325         EncodingSpecificOperations();
8326         rotated = ROR(R[m], rotation);
8327         R[d] = SignExtend(rotated<7:0>, 32);
8328 #endif
8329 
8330   bool success = false;
8331 
8332   if (ConditionPassed(opcode)) {
8333     uint32_t d;
8334     uint32_t m;
8335     uint32_t rotation;
8336 
8337     // EncodingSpecificOperations();
8338     switch (encoding) {
8339     case eEncodingT1:
8340       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8341       d = Bits32(opcode, 2, 0);
8342       m = Bits32(opcode, 5, 3);
8343       rotation = 0;
8344 
8345       break;
8346 
8347     case eEncodingT2:
8348       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8349       d = Bits32(opcode, 11, 8);
8350       m = Bits32(opcode, 3, 0);
8351       rotation = Bits32(opcode, 5, 4) << 3;
8352 
8353       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8354       if (BadReg(d) || BadReg(m))
8355         return false;
8356 
8357       break;
8358 
8359     case eEncodingA1:
8360       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8361       d = Bits32(opcode, 15, 12);
8362       m = Bits32(opcode, 3, 0);
8363       rotation = Bits32(opcode, 11, 10) << 3;
8364 
8365       // if d == 15 || m == 15 then UNPREDICTABLE;
8366       if ((d == 15) || (m == 15))
8367         return false;
8368 
8369       break;
8370 
8371     default:
8372       return false;
8373     }
8374 
8375     uint64_t Rm =
8376         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8377     if (!success)
8378       return false;
8379 
8380     // rotated = ROR(R[m], rotation);
8381     uint64_t rotated = ROR(Rm, rotation, &success);
8382     if (!success)
8383       return false;
8384 
8385     // R[d] = SignExtend(rotated<7:0>, 32);
8386     int64_t data = llvm::SignExtend64<8>(rotated);
8387 
8388     std::optional<RegisterInfo> source_reg =
8389         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8390 
8391     EmulateInstruction::Context context;
8392     context.type = eContextRegisterLoad;
8393     context.SetRegister(*source_reg);
8394 
8395     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8396                                (uint64_t)data))
8397       return false;
8398   }
8399   return true;
8400 }
8401 
8402 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8403 // writes the result to the destination
8404 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8405 // extracting the 16-bit value.
EmulateSXTH(const uint32_t opcode,const ARMEncoding encoding)8406 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8407                                         const ARMEncoding encoding) {
8408 #if 0
8409     if ConditionPassed() then
8410         EncodingSpecificOperations();
8411         rotated = ROR(R[m], rotation);
8412         R[d] = SignExtend(rotated<15:0>, 32);
8413 #endif
8414 
8415   bool success = false;
8416 
8417   if (ConditionPassed(opcode)) {
8418     uint32_t d;
8419     uint32_t m;
8420     uint32_t rotation;
8421 
8422     // EncodingSpecificOperations();
8423     switch (encoding) {
8424     case eEncodingT1:
8425       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8426       d = Bits32(opcode, 2, 0);
8427       m = Bits32(opcode, 5, 3);
8428       rotation = 0;
8429 
8430       break;
8431 
8432     case eEncodingT2:
8433       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8434       d = Bits32(opcode, 11, 8);
8435       m = Bits32(opcode, 3, 0);
8436       rotation = Bits32(opcode, 5, 4) << 3;
8437 
8438       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8439       if (BadReg(d) || BadReg(m))
8440         return false;
8441 
8442       break;
8443 
8444     case eEncodingA1:
8445       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8446       d = Bits32(opcode, 15, 12);
8447       m = Bits32(opcode, 3, 0);
8448       rotation = Bits32(opcode, 11, 10) << 3;
8449 
8450       // if d == 15 || m == 15 then UNPREDICTABLE;
8451       if ((d == 15) || (m == 15))
8452         return false;
8453 
8454       break;
8455 
8456     default:
8457       return false;
8458     }
8459 
8460     uint64_t Rm =
8461         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8462     if (!success)
8463       return false;
8464 
8465     // rotated = ROR(R[m], rotation);
8466     uint64_t rotated = ROR(Rm, rotation, &success);
8467     if (!success)
8468       return false;
8469 
8470     // R[d] = SignExtend(rotated<15:0>, 32);
8471     std::optional<RegisterInfo> source_reg =
8472         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8473 
8474     EmulateInstruction::Context context;
8475     context.type = eContextRegisterLoad;
8476     context.SetRegister(*source_reg);
8477 
8478     int64_t data = llvm::SignExtend64<16>(rotated);
8479     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8480                                (uint64_t)data))
8481       return false;
8482   }
8483 
8484   return true;
8485 }
8486 
8487 // UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and
8488 // writes the result to the destination
8489 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8490 // extracting the 8-bit value.
EmulateUXTB(const uint32_t opcode,const ARMEncoding encoding)8491 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8492                                         const ARMEncoding encoding) {
8493 #if 0
8494     if ConditionPassed() then
8495         EncodingSpecificOperations();
8496         rotated = ROR(R[m], rotation);
8497         R[d] = ZeroExtend(rotated<7:0>, 32);
8498 #endif
8499 
8500   bool success = false;
8501 
8502   if (ConditionPassed(opcode)) {
8503     uint32_t d;
8504     uint32_t m;
8505     uint32_t rotation;
8506 
8507     // EncodingSpecificOperations();
8508     switch (encoding) {
8509     case eEncodingT1:
8510       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8511       d = Bits32(opcode, 2, 0);
8512       m = Bits32(opcode, 5, 3);
8513       rotation = 0;
8514 
8515       break;
8516 
8517     case eEncodingT2:
8518       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8519       d = Bits32(opcode, 11, 8);
8520       m = Bits32(opcode, 3, 0);
8521       rotation = Bits32(opcode, 5, 4) << 3;
8522 
8523       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8524       if (BadReg(d) || BadReg(m))
8525         return false;
8526 
8527       break;
8528 
8529     case eEncodingA1:
8530       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8531       d = Bits32(opcode, 15, 12);
8532       m = Bits32(opcode, 3, 0);
8533       rotation = Bits32(opcode, 11, 10) << 3;
8534 
8535       // if d == 15 || m == 15 then UNPREDICTABLE;
8536       if ((d == 15) || (m == 15))
8537         return false;
8538 
8539       break;
8540 
8541     default:
8542       return false;
8543     }
8544 
8545     uint64_t Rm =
8546         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8547     if (!success)
8548       return false;
8549 
8550     // rotated = ROR(R[m], rotation);
8551     uint64_t rotated = ROR(Rm, rotation, &success);
8552     if (!success)
8553       return false;
8554 
8555     // R[d] = ZeroExtend(rotated<7:0>, 32);
8556     std::optional<RegisterInfo> source_reg =
8557         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8558 
8559     EmulateInstruction::Context context;
8560     context.type = eContextRegisterLoad;
8561     context.SetRegister(*source_reg);
8562 
8563     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8564                                Bits32(rotated, 7, 0)))
8565       return false;
8566   }
8567   return true;
8568 }
8569 
8570 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8571 // writes the result to the destination
8572 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8573 // extracting the 16-bit value.
EmulateUXTH(const uint32_t opcode,const ARMEncoding encoding)8574 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8575                                         const ARMEncoding encoding) {
8576 #if 0
8577     if ConditionPassed() then
8578         EncodingSpecificOperations();
8579         rotated = ROR(R[m], rotation);
8580         R[d] = ZeroExtend(rotated<15:0>, 32);
8581 #endif
8582 
8583   bool success = false;
8584 
8585   if (ConditionPassed(opcode)) {
8586     uint32_t d;
8587     uint32_t m;
8588     uint32_t rotation;
8589 
8590     switch (encoding) {
8591     case eEncodingT1:
8592       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8593       d = Bits32(opcode, 2, 0);
8594       m = Bits32(opcode, 5, 3);
8595       rotation = 0;
8596 
8597       break;
8598 
8599     case eEncodingT2:
8600       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8601       d = Bits32(opcode, 11, 8);
8602       m = Bits32(opcode, 3, 0);
8603       rotation = Bits32(opcode, 5, 4) << 3;
8604 
8605       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8606       if (BadReg(d) || BadReg(m))
8607         return false;
8608 
8609       break;
8610 
8611     case eEncodingA1:
8612       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8613       d = Bits32(opcode, 15, 12);
8614       m = Bits32(opcode, 3, 0);
8615       rotation = Bits32(opcode, 11, 10) << 3;
8616 
8617       // if d == 15 || m == 15 then UNPREDICTABLE;
8618       if ((d == 15) || (m == 15))
8619         return false;
8620 
8621       break;
8622 
8623     default:
8624       return false;
8625     }
8626 
8627     uint64_t Rm =
8628         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8629     if (!success)
8630       return false;
8631 
8632     // rotated = ROR(R[m], rotation);
8633     uint64_t rotated = ROR(Rm, rotation, &success);
8634     if (!success)
8635       return false;
8636 
8637     // R[d] = ZeroExtend(rotated<15:0>, 32);
8638     std::optional<RegisterInfo> source_reg =
8639         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
8640 
8641     EmulateInstruction::Context context;
8642     context.type = eContextRegisterLoad;
8643     context.SetRegister(*source_reg);
8644 
8645     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8646                                Bits32(rotated, 15, 0)))
8647       return false;
8648   }
8649   return true;
8650 }
8651 
8652 // RFE (Return From Exception) loads the PC and the CPSR from the word at the
8653 // specified address and the following
8654 // word respectively.
EmulateRFE(const uint32_t opcode,const ARMEncoding encoding)8655 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8656                                        const ARMEncoding encoding) {
8657 #if 0
8658     if ConditionPassed() then
8659         EncodingSpecificOperations();
8660         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8661             UNPREDICTABLE;
8662         else
8663             address = if increment then R[n] else R[n]-8;
8664             if wordhigher then address = address+4;
8665             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8666             BranchWritePC(MemA[address,4]);
8667             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8668 #endif
8669 
8670   bool success = false;
8671 
8672   if (ConditionPassed(opcode)) {
8673     uint32_t n;
8674     bool wback;
8675     bool increment;
8676     bool wordhigher;
8677 
8678     // EncodingSpecificOperations();
8679     switch (encoding) {
8680     case eEncodingT1:
8681       // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8682       // FALSE;
8683       n = Bits32(opcode, 19, 16);
8684       wback = BitIsSet(opcode, 21);
8685       increment = false;
8686       wordhigher = false;
8687 
8688       // if n == 15 then UNPREDICTABLE;
8689       if (n == 15)
8690         return false;
8691 
8692       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8693       if (InITBlock() && !LastInITBlock())
8694         return false;
8695 
8696       break;
8697 
8698     case eEncodingT2:
8699       // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8700       n = Bits32(opcode, 19, 16);
8701       wback = BitIsSet(opcode, 21);
8702       increment = true;
8703       wordhigher = false;
8704 
8705       // if n == 15 then UNPREDICTABLE;
8706       if (n == 15)
8707         return false;
8708 
8709       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8710       if (InITBlock() && !LastInITBlock())
8711         return false;
8712 
8713       break;
8714 
8715     case eEncodingA1:
8716       // n = UInt(Rn);
8717       n = Bits32(opcode, 19, 16);
8718 
8719       // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8720       wback = BitIsSet(opcode, 21);
8721       increment = BitIsSet(opcode, 23);
8722       wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8723 
8724       // if n == 15 then UNPREDICTABLE;
8725       if (n == 15)
8726         return false;
8727 
8728       break;
8729 
8730     default:
8731       return false;
8732     }
8733 
8734     // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8735     // then
8736     if (!CurrentModeIsPrivileged())
8737       // UNPREDICTABLE;
8738       return false;
8739     else {
8740       uint64_t Rn =
8741           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8742       if (!success)
8743         return false;
8744 
8745       addr_t address;
8746       // address = if increment then R[n] else R[n]-8;
8747       if (increment)
8748         address = Rn;
8749       else
8750         address = Rn - 8;
8751 
8752       // if wordhigher then address = address+4;
8753       if (wordhigher)
8754         address = address + 4;
8755 
8756       // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8757       std::optional<RegisterInfo> base_reg =
8758           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
8759 
8760       EmulateInstruction::Context context;
8761       context.type = eContextReturnFromException;
8762       context.SetRegisterPlusOffset(*base_reg, address - Rn);
8763 
8764       uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8765       if (!success)
8766         return false;
8767 
8768       CPSRWriteByInstr(data, 15, true);
8769 
8770       // BranchWritePC(MemA[address,4]);
8771       uint64_t data2 = MemARead(context, address, 4, 0, &success);
8772       if (!success)
8773         return false;
8774 
8775       BranchWritePC(context, data2);
8776 
8777       // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8778       if (wback) {
8779         context.type = eContextAdjustBaseRegister;
8780         if (increment) {
8781           context.SetOffset(8);
8782           if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8783                                      Rn + 8))
8784             return false;
8785         } else {
8786           context.SetOffset(-8);
8787           if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8788                                      Rn - 8))
8789             return false;
8790         }
8791       } // if wback
8792     }
8793   } // if ConditionPassed()
8794   return true;
8795 }
8796 
8797 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8798 // register value and an immediate value, and writes the result to the
8799 // destination register.  It can optionally update the condition flags based on
8800 // the result.
EmulateEORImm(const uint32_t opcode,const ARMEncoding encoding)8801 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8802                                           const ARMEncoding encoding) {
8803 #if 0
8804     // ARM pseudo code...
8805     if ConditionPassed() then
8806         EncodingSpecificOperations();
8807         result = R[n] EOR imm32;
8808         if d == 15 then         // Can only occur for ARM encoding
8809             ALUWritePC(result); // setflags is always FALSE here
8810         else
8811             R[d] = result;
8812             if setflags then
8813                 APSR.N = result<31>;
8814                 APSR.Z = IsZeroBit(result);
8815                 APSR.C = carry;
8816                 // APSR.V unchanged
8817 #endif
8818 
8819   bool success = false;
8820 
8821   if (ConditionPassed(opcode)) {
8822     uint32_t Rd, Rn;
8823     uint32_t
8824         imm32; // the immediate value to be ORed to the value obtained from Rn
8825     bool setflags;
8826     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8827     switch (encoding) {
8828     case eEncodingT1:
8829       Rd = Bits32(opcode, 11, 8);
8830       Rn = Bits32(opcode, 19, 16);
8831       setflags = BitIsSet(opcode, 20);
8832       imm32 = ThumbExpandImm_C(
8833           opcode, APSR_C,
8834           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8835       // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8836       if (Rd == 15 && setflags)
8837         return EmulateTEQImm(opcode, eEncodingT1);
8838       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8839         return false;
8840       break;
8841     case eEncodingA1:
8842       Rd = Bits32(opcode, 15, 12);
8843       Rn = Bits32(opcode, 19, 16);
8844       setflags = BitIsSet(opcode, 20);
8845       imm32 =
8846           ARMExpandImm_C(opcode, APSR_C,
8847                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8848 
8849       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8850       // instructions;
8851       if (Rd == 15 && setflags)
8852         return EmulateSUBSPcLrEtc(opcode, encoding);
8853       break;
8854     default:
8855       return false;
8856     }
8857 
8858     // Read the first operand.
8859     uint32_t val1 = ReadCoreReg(Rn, &success);
8860     if (!success)
8861       return false;
8862 
8863     uint32_t result = val1 ^ imm32;
8864 
8865     EmulateInstruction::Context context;
8866     context.type = EmulateInstruction::eContextImmediate;
8867     context.SetNoArgs();
8868 
8869     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8870       return false;
8871   }
8872   return true;
8873 }
8874 
8875 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8876 // register value and an optionally-shifted register value, and writes the
8877 // result to the destination register. It can optionally update the condition
8878 // flags based on the result.
EmulateEORReg(const uint32_t opcode,const ARMEncoding encoding)8879 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8880                                           const ARMEncoding encoding) {
8881 #if 0
8882     // ARM pseudo code...
8883     if ConditionPassed() then
8884         EncodingSpecificOperations();
8885         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8886         result = R[n] EOR shifted;
8887         if d == 15 then         // Can only occur for ARM encoding
8888             ALUWritePC(result); // setflags is always FALSE here
8889         else
8890             R[d] = result;
8891             if setflags then
8892                 APSR.N = result<31>;
8893                 APSR.Z = IsZeroBit(result);
8894                 APSR.C = carry;
8895                 // APSR.V unchanged
8896 #endif
8897 
8898   bool success = false;
8899 
8900   if (ConditionPassed(opcode)) {
8901     uint32_t Rd, Rn, Rm;
8902     ARM_ShifterType shift_t;
8903     uint32_t shift_n; // the shift applied to the value read from Rm
8904     bool setflags;
8905     uint32_t carry;
8906     switch (encoding) {
8907     case eEncodingT1:
8908       Rd = Rn = Bits32(opcode, 2, 0);
8909       Rm = Bits32(opcode, 5, 3);
8910       setflags = !InITBlock();
8911       shift_t = SRType_LSL;
8912       shift_n = 0;
8913       break;
8914     case eEncodingT2:
8915       Rd = Bits32(opcode, 11, 8);
8916       Rn = Bits32(opcode, 19, 16);
8917       Rm = Bits32(opcode, 3, 0);
8918       setflags = BitIsSet(opcode, 20);
8919       shift_n = DecodeImmShiftThumb(opcode, shift_t);
8920       // if Rd == '1111' && S == '1' then SEE TEQ (register);
8921       if (Rd == 15 && setflags)
8922         return EmulateTEQReg(opcode, eEncodingT1);
8923       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8924         return false;
8925       break;
8926     case eEncodingA1:
8927       Rd = Bits32(opcode, 15, 12);
8928       Rn = Bits32(opcode, 19, 16);
8929       Rm = Bits32(opcode, 3, 0);
8930       setflags = BitIsSet(opcode, 20);
8931       shift_n = DecodeImmShiftARM(opcode, shift_t);
8932 
8933       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8934       // instructions;
8935       if (Rd == 15 && setflags)
8936         return EmulateSUBSPcLrEtc(opcode, encoding);
8937       break;
8938     default:
8939       return false;
8940     }
8941 
8942     // Read the first operand.
8943     uint32_t val1 = ReadCoreReg(Rn, &success);
8944     if (!success)
8945       return false;
8946 
8947     // Read the second operand.
8948     uint32_t val2 = ReadCoreReg(Rm, &success);
8949     if (!success)
8950       return false;
8951 
8952     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8953     if (!success)
8954       return false;
8955     uint32_t result = val1 ^ shifted;
8956 
8957     EmulateInstruction::Context context;
8958     context.type = EmulateInstruction::eContextImmediate;
8959     context.SetNoArgs();
8960 
8961     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8962       return false;
8963   }
8964   return true;
8965 }
8966 
8967 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8968 // and an immediate value, and writes the result to the destination register.
8969 // It can optionally update the condition flags based on the result.
EmulateORRImm(const uint32_t opcode,const ARMEncoding encoding)8970 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8971                                           const ARMEncoding encoding) {
8972 #if 0
8973     // ARM pseudo code...
8974     if ConditionPassed() then
8975         EncodingSpecificOperations();
8976         result = R[n] OR imm32;
8977         if d == 15 then         // Can only occur for ARM encoding
8978             ALUWritePC(result); // setflags is always FALSE here
8979         else
8980             R[d] = result;
8981             if setflags then
8982                 APSR.N = result<31>;
8983                 APSR.Z = IsZeroBit(result);
8984                 APSR.C = carry;
8985                 // APSR.V unchanged
8986 #endif
8987 
8988   bool success = false;
8989 
8990   if (ConditionPassed(opcode)) {
8991     uint32_t Rd, Rn;
8992     uint32_t
8993         imm32; // the immediate value to be ORed to the value obtained from Rn
8994     bool setflags;
8995     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8996     switch (encoding) {
8997     case eEncodingT1:
8998       Rd = Bits32(opcode, 11, 8);
8999       Rn = Bits32(opcode, 19, 16);
9000       setflags = BitIsSet(opcode, 20);
9001       imm32 = ThumbExpandImm_C(
9002           opcode, APSR_C,
9003           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9004       // if Rn == '1111' then SEE MOV (immediate);
9005       if (Rn == 15)
9006         return EmulateMOVRdImm(opcode, eEncodingT2);
9007       if (BadReg(Rd) || Rn == 13)
9008         return false;
9009       break;
9010     case eEncodingA1:
9011       Rd = Bits32(opcode, 15, 12);
9012       Rn = Bits32(opcode, 19, 16);
9013       setflags = BitIsSet(opcode, 20);
9014       imm32 =
9015           ARMExpandImm_C(opcode, APSR_C,
9016                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9017 
9018       if (Rd == 15 && setflags)
9019         return EmulateSUBSPcLrEtc(opcode, encoding);
9020       break;
9021     default:
9022       return false;
9023     }
9024 
9025     // Read the first operand.
9026     uint32_t val1 = ReadCoreReg(Rn, &success);
9027     if (!success)
9028       return false;
9029 
9030     uint32_t result = val1 | imm32;
9031 
9032     EmulateInstruction::Context context;
9033     context.type = EmulateInstruction::eContextImmediate;
9034     context.SetNoArgs();
9035 
9036     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9037       return false;
9038   }
9039   return true;
9040 }
9041 
9042 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9043 // and an optionally-shifted register value, and writes the result to the
9044 // destination register.  It can optionally update the condition flags based on
9045 // the result.
EmulateORRReg(const uint32_t opcode,const ARMEncoding encoding)9046 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9047                                           const ARMEncoding encoding) {
9048 #if 0
9049     // ARM pseudo code...
9050     if ConditionPassed() then
9051         EncodingSpecificOperations();
9052         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9053         result = R[n] OR shifted;
9054         if d == 15 then         // Can only occur for ARM encoding
9055             ALUWritePC(result); // setflags is always FALSE here
9056         else
9057             R[d] = result;
9058             if setflags then
9059                 APSR.N = result<31>;
9060                 APSR.Z = IsZeroBit(result);
9061                 APSR.C = carry;
9062                 // APSR.V unchanged
9063 #endif
9064 
9065   bool success = false;
9066 
9067   if (ConditionPassed(opcode)) {
9068     uint32_t Rd, Rn, Rm;
9069     ARM_ShifterType shift_t;
9070     uint32_t shift_n; // the shift applied to the value read from Rm
9071     bool setflags;
9072     uint32_t carry;
9073     switch (encoding) {
9074     case eEncodingT1:
9075       Rd = Rn = Bits32(opcode, 2, 0);
9076       Rm = Bits32(opcode, 5, 3);
9077       setflags = !InITBlock();
9078       shift_t = SRType_LSL;
9079       shift_n = 0;
9080       break;
9081     case eEncodingT2:
9082       Rd = Bits32(opcode, 11, 8);
9083       Rn = Bits32(opcode, 19, 16);
9084       Rm = Bits32(opcode, 3, 0);
9085       setflags = BitIsSet(opcode, 20);
9086       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9087       // if Rn == '1111' then SEE MOV (register);
9088       if (Rn == 15)
9089         return EmulateMOVRdRm(opcode, eEncodingT3);
9090       if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9091         return false;
9092       break;
9093     case eEncodingA1:
9094       Rd = Bits32(opcode, 15, 12);
9095       Rn = Bits32(opcode, 19, 16);
9096       Rm = Bits32(opcode, 3, 0);
9097       setflags = BitIsSet(opcode, 20);
9098       shift_n = DecodeImmShiftARM(opcode, shift_t);
9099 
9100       if (Rd == 15 && setflags)
9101         return EmulateSUBSPcLrEtc(opcode, encoding);
9102       break;
9103     default:
9104       return false;
9105     }
9106 
9107     // Read the first operand.
9108     uint32_t val1 = ReadCoreReg(Rn, &success);
9109     if (!success)
9110       return false;
9111 
9112     // Read the second operand.
9113     uint32_t val2 = ReadCoreReg(Rm, &success);
9114     if (!success)
9115       return false;
9116 
9117     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9118     if (!success)
9119       return false;
9120     uint32_t result = val1 | shifted;
9121 
9122     EmulateInstruction::Context context;
9123     context.type = EmulateInstruction::eContextImmediate;
9124     context.SetNoArgs();
9125 
9126     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9127       return false;
9128   }
9129   return true;
9130 }
9131 
9132 // Reverse Subtract (immediate) subtracts a register value from an immediate
9133 // value, and writes the result to the destination register. It can optionally
9134 // update the condition flags based on the result.
EmulateRSBImm(const uint32_t opcode,const ARMEncoding encoding)9135 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9136                                           const ARMEncoding encoding) {
9137 #if 0
9138     // ARM pseudo code...
9139     if ConditionPassed() then
9140         EncodingSpecificOperations();
9141         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9142         if d == 15 then         // Can only occur for ARM encoding
9143             ALUWritePC(result); // setflags is always FALSE here
9144         else
9145             R[d] = result;
9146             if setflags then
9147                 APSR.N = result<31>;
9148                 APSR.Z = IsZeroBit(result);
9149                 APSR.C = carry;
9150                 APSR.V = overflow;
9151 #endif
9152 
9153   bool success = false;
9154 
9155   uint32_t Rd; // the destination register
9156   uint32_t Rn; // the first operand
9157   bool setflags;
9158   uint32_t
9159       imm32; // the immediate value to be added to the value obtained from Rn
9160   switch (encoding) {
9161   case eEncodingT1:
9162     Rd = Bits32(opcode, 2, 0);
9163     Rn = Bits32(opcode, 5, 3);
9164     setflags = !InITBlock();
9165     imm32 = 0;
9166     break;
9167   case eEncodingT2:
9168     Rd = Bits32(opcode, 11, 8);
9169     Rn = Bits32(opcode, 19, 16);
9170     setflags = BitIsSet(opcode, 20);
9171     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9172     if (BadReg(Rd) || BadReg(Rn))
9173       return false;
9174     break;
9175   case eEncodingA1:
9176     Rd = Bits32(opcode, 15, 12);
9177     Rn = Bits32(opcode, 19, 16);
9178     setflags = BitIsSet(opcode, 20);
9179     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9180 
9181     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9182     // instructions;
9183     if (Rd == 15 && setflags)
9184       return EmulateSUBSPcLrEtc(opcode, encoding);
9185     break;
9186   default:
9187     return false;
9188   }
9189   // Read the register value from the operand register Rn.
9190   uint32_t reg_val = ReadCoreReg(Rn, &success);
9191   if (!success)
9192     return false;
9193 
9194   AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9195 
9196   EmulateInstruction::Context context;
9197   context.type = EmulateInstruction::eContextImmediate;
9198   context.SetNoArgs();
9199 
9200   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9201                                    res.carry_out, res.overflow);
9202 }
9203 
9204 // Reverse Subtract (register) subtracts a register value from an optionally-
9205 // shifted register value, and writes the result to the destination register.
9206 // It can optionally update the condition flags based on the result.
EmulateRSBReg(const uint32_t opcode,const ARMEncoding encoding)9207 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9208                                           const ARMEncoding encoding) {
9209 #if 0
9210     // ARM pseudo code...
9211     if ConditionPassed() then
9212         EncodingSpecificOperations();
9213         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9214         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9215         if d == 15 then         // Can only occur for ARM encoding
9216             ALUWritePC(result); // setflags is always FALSE here
9217         else
9218             R[d] = result;
9219             if setflags then
9220                 APSR.N = result<31>;
9221                 APSR.Z = IsZeroBit(result);
9222                 APSR.C = carry;
9223                 APSR.V = overflow;
9224 #endif
9225 
9226   bool success = false;
9227 
9228   uint32_t Rd; // the destination register
9229   uint32_t Rn; // the first operand
9230   uint32_t Rm; // the second operand
9231   bool setflags;
9232   ARM_ShifterType shift_t;
9233   uint32_t shift_n; // the shift applied to the value read from Rm
9234   switch (encoding) {
9235   case eEncodingT1:
9236     Rd = Bits32(opcode, 11, 8);
9237     Rn = Bits32(opcode, 19, 16);
9238     Rm = Bits32(opcode, 3, 0);
9239     setflags = BitIsSet(opcode, 20);
9240     shift_n = DecodeImmShiftThumb(opcode, shift_t);
9241     // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9242     if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9243       return false;
9244     break;
9245   case eEncodingA1:
9246     Rd = Bits32(opcode, 15, 12);
9247     Rn = Bits32(opcode, 19, 16);
9248     Rm = Bits32(opcode, 3, 0);
9249     setflags = BitIsSet(opcode, 20);
9250     shift_n = DecodeImmShiftARM(opcode, shift_t);
9251 
9252     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9253     // instructions;
9254     if (Rd == 15 && setflags)
9255       return EmulateSUBSPcLrEtc(opcode, encoding);
9256     break;
9257   default:
9258     return false;
9259   }
9260   // Read the register value from register Rn.
9261   uint32_t val1 = ReadCoreReg(Rn, &success);
9262   if (!success)
9263     return false;
9264 
9265   // Read the register value from register Rm.
9266   uint32_t val2 = ReadCoreReg(Rm, &success);
9267   if (!success)
9268     return false;
9269 
9270   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9271   if (!success)
9272     return false;
9273   AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9274 
9275   EmulateInstruction::Context context;
9276   context.type = EmulateInstruction::eContextImmediate;
9277   context.SetNoArgs();
9278   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9279                                    res.carry_out, res.overflow);
9280 }
9281 
9282 // Reverse Subtract with Carry (immediate) subtracts a register value and the
9283 // value of NOT (Carry flag) from an immediate value, and writes the result to
9284 // the destination register. It can optionally update the condition flags based
9285 // on the result.
EmulateRSCImm(const uint32_t opcode,const ARMEncoding encoding)9286 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9287                                           const ARMEncoding encoding) {
9288 #if 0
9289     // ARM pseudo code...
9290     if ConditionPassed() then
9291         EncodingSpecificOperations();
9292         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9293         if d == 15 then
9294             ALUWritePC(result); // setflags is always FALSE here
9295         else
9296             R[d] = result;
9297             if setflags then
9298                 APSR.N = result<31>;
9299                 APSR.Z = IsZeroBit(result);
9300                 APSR.C = carry;
9301                 APSR.V = overflow;
9302 #endif
9303 
9304   bool success = false;
9305 
9306   uint32_t Rd; // the destination register
9307   uint32_t Rn; // the first operand
9308   bool setflags;
9309   uint32_t
9310       imm32; // the immediate value to be added to the value obtained from Rn
9311   switch (encoding) {
9312   case eEncodingA1:
9313     Rd = Bits32(opcode, 15, 12);
9314     Rn = Bits32(opcode, 19, 16);
9315     setflags = BitIsSet(opcode, 20);
9316     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9317 
9318     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9319     // instructions;
9320     if (Rd == 15 && setflags)
9321       return EmulateSUBSPcLrEtc(opcode, encoding);
9322     break;
9323   default:
9324     return false;
9325   }
9326   // Read the register value from the operand register Rn.
9327   uint32_t reg_val = ReadCoreReg(Rn, &success);
9328   if (!success)
9329     return false;
9330 
9331   AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9332 
9333   EmulateInstruction::Context context;
9334   context.type = EmulateInstruction::eContextImmediate;
9335   context.SetNoArgs();
9336 
9337   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9338                                    res.carry_out, res.overflow);
9339 }
9340 
9341 // Reverse Subtract with Carry (register) subtracts a register value and the
9342 // value of NOT (Carry flag) from an optionally-shifted register value, and
9343 // writes the result to the destination register. It can optionally update the
9344 // condition flags based on the result.
EmulateRSCReg(const uint32_t opcode,const ARMEncoding encoding)9345 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9346                                           const ARMEncoding encoding) {
9347 #if 0
9348     // ARM pseudo code...
9349     if ConditionPassed() then
9350         EncodingSpecificOperations();
9351         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9352         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9353         if d == 15 then
9354             ALUWritePC(result); // setflags is always FALSE here
9355         else
9356             R[d] = result;
9357             if setflags then
9358                 APSR.N = result<31>;
9359                 APSR.Z = IsZeroBit(result);
9360                 APSR.C = carry;
9361                 APSR.V = overflow;
9362 #endif
9363 
9364   bool success = false;
9365 
9366   uint32_t Rd; // the destination register
9367   uint32_t Rn; // the first operand
9368   uint32_t Rm; // the second operand
9369   bool setflags;
9370   ARM_ShifterType shift_t;
9371   uint32_t shift_n; // the shift applied to the value read from Rm
9372   switch (encoding) {
9373   case eEncodingA1:
9374     Rd = Bits32(opcode, 15, 12);
9375     Rn = Bits32(opcode, 19, 16);
9376     Rm = Bits32(opcode, 3, 0);
9377     setflags = BitIsSet(opcode, 20);
9378     shift_n = DecodeImmShiftARM(opcode, shift_t);
9379 
9380     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9381     // instructions;
9382     if (Rd == 15 && setflags)
9383       return EmulateSUBSPcLrEtc(opcode, encoding);
9384     break;
9385   default:
9386     return false;
9387   }
9388   // Read the register value from register Rn.
9389   uint32_t val1 = ReadCoreReg(Rn, &success);
9390   if (!success)
9391     return false;
9392 
9393   // Read the register value from register Rm.
9394   uint32_t val2 = ReadCoreReg(Rm, &success);
9395   if (!success)
9396     return false;
9397 
9398   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9399   if (!success)
9400     return false;
9401   AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9402 
9403   EmulateInstruction::Context context;
9404   context.type = EmulateInstruction::eContextImmediate;
9405   context.SetNoArgs();
9406   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9407                                    res.carry_out, res.overflow);
9408 }
9409 
9410 // Subtract with Carry (immediate) subtracts an immediate value and the value
9411 // of
9412 // NOT (Carry flag) from a register value, and writes the result to the
9413 // destination register.
9414 // It can optionally update the condition flags based on the result.
EmulateSBCImm(const uint32_t opcode,const ARMEncoding encoding)9415 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9416                                           const ARMEncoding encoding) {
9417 #if 0
9418     // ARM pseudo code...
9419     if ConditionPassed() then
9420         EncodingSpecificOperations();
9421         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9422         if d == 15 then         // Can only occur for ARM encoding
9423             ALUWritePC(result); // setflags is always FALSE here
9424         else
9425             R[d] = result;
9426             if setflags then
9427                 APSR.N = result<31>;
9428                 APSR.Z = IsZeroBit(result);
9429                 APSR.C = carry;
9430                 APSR.V = overflow;
9431 #endif
9432 
9433   bool success = false;
9434 
9435   uint32_t Rd; // the destination register
9436   uint32_t Rn; // the first operand
9437   bool setflags;
9438   uint32_t
9439       imm32; // the immediate value to be added to the value obtained from Rn
9440   switch (encoding) {
9441   case eEncodingT1:
9442     Rd = Bits32(opcode, 11, 8);
9443     Rn = Bits32(opcode, 19, 16);
9444     setflags = BitIsSet(opcode, 20);
9445     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9446     if (BadReg(Rd) || BadReg(Rn))
9447       return false;
9448     break;
9449   case eEncodingA1:
9450     Rd = Bits32(opcode, 15, 12);
9451     Rn = Bits32(opcode, 19, 16);
9452     setflags = BitIsSet(opcode, 20);
9453     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9454 
9455     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9456     // instructions;
9457     if (Rd == 15 && setflags)
9458       return EmulateSUBSPcLrEtc(opcode, encoding);
9459     break;
9460   default:
9461     return false;
9462   }
9463   // Read the register value from the operand register Rn.
9464   uint32_t reg_val = ReadCoreReg(Rn, &success);
9465   if (!success)
9466     return false;
9467 
9468   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9469 
9470   EmulateInstruction::Context context;
9471   context.type = EmulateInstruction::eContextImmediate;
9472   context.SetNoArgs();
9473 
9474   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9475                                    res.carry_out, res.overflow);
9476 }
9477 
9478 // Subtract with Carry (register) subtracts an optionally-shifted register
9479 // value and the value of
9480 // NOT (Carry flag) from a register value, and writes the result to the
9481 // destination register.
9482 // It can optionally update the condition flags based on the result.
EmulateSBCReg(const uint32_t opcode,const ARMEncoding encoding)9483 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9484                                           const ARMEncoding encoding) {
9485 #if 0
9486     // ARM pseudo code...
9487     if ConditionPassed() then
9488         EncodingSpecificOperations();
9489         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9490         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9491         if d == 15 then         // Can only occur for ARM encoding
9492             ALUWritePC(result); // setflags is always FALSE here
9493         else
9494             R[d] = result;
9495             if setflags then
9496                 APSR.N = result<31>;
9497                 APSR.Z = IsZeroBit(result);
9498                 APSR.C = carry;
9499                 APSR.V = overflow;
9500 #endif
9501 
9502   bool success = false;
9503 
9504   uint32_t Rd; // the destination register
9505   uint32_t Rn; // the first operand
9506   uint32_t Rm; // the second operand
9507   bool setflags;
9508   ARM_ShifterType shift_t;
9509   uint32_t shift_n; // the shift applied to the value read from Rm
9510   switch (encoding) {
9511   case eEncodingT1:
9512     Rd = Rn = Bits32(opcode, 2, 0);
9513     Rm = Bits32(opcode, 5, 3);
9514     setflags = !InITBlock();
9515     shift_t = SRType_LSL;
9516     shift_n = 0;
9517     break;
9518   case eEncodingT2:
9519     Rd = Bits32(opcode, 11, 8);
9520     Rn = Bits32(opcode, 19, 16);
9521     Rm = Bits32(opcode, 3, 0);
9522     setflags = BitIsSet(opcode, 20);
9523     shift_n = DecodeImmShiftThumb(opcode, shift_t);
9524     if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9525       return false;
9526     break;
9527   case eEncodingA1:
9528     Rd = Bits32(opcode, 15, 12);
9529     Rn = Bits32(opcode, 19, 16);
9530     Rm = Bits32(opcode, 3, 0);
9531     setflags = BitIsSet(opcode, 20);
9532     shift_n = DecodeImmShiftARM(opcode, shift_t);
9533 
9534     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9535     // instructions;
9536     if (Rd == 15 && setflags)
9537       return EmulateSUBSPcLrEtc(opcode, encoding);
9538     break;
9539   default:
9540     return false;
9541   }
9542   // Read the register value from register Rn.
9543   uint32_t val1 = ReadCoreReg(Rn, &success);
9544   if (!success)
9545     return false;
9546 
9547   // Read the register value from register Rm.
9548   uint32_t val2 = ReadCoreReg(Rm, &success);
9549   if (!success)
9550     return false;
9551 
9552   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9553   if (!success)
9554     return false;
9555   AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9556 
9557   EmulateInstruction::Context context;
9558   context.type = EmulateInstruction::eContextImmediate;
9559   context.SetNoArgs();
9560   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9561                                    res.carry_out, res.overflow);
9562 }
9563 
9564 // This instruction subtracts an immediate value from a register value, and
9565 // writes the result to the destination register.  It can optionally update the
9566 // condition flags based on the result.
EmulateSUBImmThumb(const uint32_t opcode,const ARMEncoding encoding)9567 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9568                                                const ARMEncoding encoding) {
9569 #if 0
9570     // ARM pseudo code...
9571     if ConditionPassed() then
9572         EncodingSpecificOperations();
9573         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9574         R[d] = result;
9575         if setflags then
9576             APSR.N = result<31>;
9577             APSR.Z = IsZeroBit(result);
9578             APSR.C = carry;
9579             APSR.V = overflow;
9580 #endif
9581 
9582   bool success = false;
9583 
9584   uint32_t Rd; // the destination register
9585   uint32_t Rn; // the first operand
9586   bool setflags;
9587   uint32_t imm32; // the immediate value to be subtracted from the value
9588                   // obtained from Rn
9589   switch (encoding) {
9590   case eEncodingT1:
9591     Rd = Bits32(opcode, 2, 0);
9592     Rn = Bits32(opcode, 5, 3);
9593     setflags = !InITBlock();
9594     imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9595     break;
9596   case eEncodingT2:
9597     Rd = Rn = Bits32(opcode, 10, 8);
9598     setflags = !InITBlock();
9599     imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9600     break;
9601   case eEncodingT3:
9602     Rd = Bits32(opcode, 11, 8);
9603     Rn = Bits32(opcode, 19, 16);
9604     setflags = BitIsSet(opcode, 20);
9605     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9606 
9607     // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9608     if (Rd == 15 && setflags)
9609       return EmulateCMPImm(opcode, eEncodingT2);
9610 
9611     // if Rn == '1101' then SEE SUB (SP minus immediate);
9612     if (Rn == 13)
9613       return EmulateSUBSPImm(opcode, eEncodingT2);
9614 
9615     // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9616     if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9617       return false;
9618     break;
9619   case eEncodingT4:
9620     Rd = Bits32(opcode, 11, 8);
9621     Rn = Bits32(opcode, 19, 16);
9622     setflags = BitIsSet(opcode, 20);
9623     imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9624 
9625     // if Rn == '1111' then SEE ADR;
9626     if (Rn == 15)
9627       return EmulateADR(opcode, eEncodingT2);
9628 
9629     // if Rn == '1101' then SEE SUB (SP minus immediate);
9630     if (Rn == 13)
9631       return EmulateSUBSPImm(opcode, eEncodingT3);
9632 
9633     if (BadReg(Rd))
9634       return false;
9635     break;
9636   default:
9637     return false;
9638   }
9639   // Read the register value from the operand register Rn.
9640   uint32_t reg_val = ReadCoreReg(Rn, &success);
9641   if (!success)
9642     return false;
9643 
9644   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9645 
9646   EmulateInstruction::Context context;
9647   context.type = EmulateInstruction::eContextImmediate;
9648   context.SetNoArgs();
9649 
9650   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9651                                    res.carry_out, res.overflow);
9652 }
9653 
9654 // This instruction subtracts an immediate value from a register value, and
9655 // writes the result to the destination register.  It can optionally update the
9656 // condition flags based on the result.
EmulateSUBImmARM(const uint32_t opcode,const ARMEncoding encoding)9657 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9658                                              const ARMEncoding encoding) {
9659 #if 0
9660     // ARM pseudo code...
9661     if ConditionPassed() then
9662         EncodingSpecificOperations();
9663         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9664         if d == 15 then
9665             ALUWritePC(result); // setflags is always FALSE here
9666         else
9667             R[d] = result;
9668             if setflags then
9669                 APSR.N = result<31>;
9670                 APSR.Z = IsZeroBit(result);
9671                 APSR.C = carry;
9672                 APSR.V = overflow;
9673 #endif
9674 
9675   bool success = false;
9676 
9677   if (ConditionPassed(opcode)) {
9678     uint32_t Rd; // the destination register
9679     uint32_t Rn; // the first operand
9680     bool setflags;
9681     uint32_t imm32; // the immediate value to be subtracted from the value
9682                     // obtained from Rn
9683     switch (encoding) {
9684     case eEncodingA1:
9685       Rd = Bits32(opcode, 15, 12);
9686       Rn = Bits32(opcode, 19, 16);
9687       setflags = BitIsSet(opcode, 20);
9688       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9689 
9690       // if Rn == '1111' && S == '0' then SEE ADR;
9691       if (Rn == 15 && !setflags)
9692         return EmulateADR(opcode, eEncodingA2);
9693 
9694       // if Rn == '1101' then SEE SUB (SP minus immediate);
9695       if (Rn == 13)
9696         return EmulateSUBSPImm(opcode, eEncodingA1);
9697 
9698       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9699       // instructions;
9700       if (Rd == 15 && setflags)
9701         return EmulateSUBSPcLrEtc(opcode, encoding);
9702       break;
9703     default:
9704       return false;
9705     }
9706     // Read the register value from the operand register Rn.
9707     uint32_t reg_val = ReadCoreReg(Rn, &success);
9708     if (!success)
9709       return false;
9710 
9711     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9712 
9713     EmulateInstruction::Context context;
9714     if (Rd == 13)
9715       context.type = EmulateInstruction::eContextAdjustStackPointer;
9716     else
9717       context.type = EmulateInstruction::eContextRegisterPlusOffset;
9718 
9719     std::optional<RegisterInfo> dwarf_reg =
9720         GetRegisterInfo(eRegisterKindDWARF, Rn);
9721     int64_t imm32_signed = imm32;
9722     context.SetRegisterPlusOffset(*dwarf_reg, -imm32_signed);
9723 
9724     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9725                                    res.carry_out, res.overflow))
9726       return false;
9727   }
9728   return true;
9729 }
9730 
9731 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9732 // register value and an immediate value.  It updates the condition flags based
9733 // on the result, and discards the result.
EmulateTEQImm(const uint32_t opcode,const ARMEncoding encoding)9734 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9735                                           const ARMEncoding encoding) {
9736 #if 0
9737     // ARM pseudo code...
9738     if ConditionPassed() then
9739         EncodingSpecificOperations();
9740         result = R[n] EOR imm32;
9741         APSR.N = result<31>;
9742         APSR.Z = IsZeroBit(result);
9743         APSR.C = carry;
9744         // APSR.V unchanged
9745 #endif
9746 
9747   bool success = false;
9748 
9749   if (ConditionPassed(opcode)) {
9750     uint32_t Rn;
9751     uint32_t
9752         imm32; // the immediate value to be ANDed to the value obtained from Rn
9753     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9754     switch (encoding) {
9755     case eEncodingT1:
9756       Rn = Bits32(opcode, 19, 16);
9757       imm32 = ThumbExpandImm_C(
9758           opcode, APSR_C,
9759           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9760       if (BadReg(Rn))
9761         return false;
9762       break;
9763     case eEncodingA1:
9764       Rn = Bits32(opcode, 19, 16);
9765       imm32 =
9766           ARMExpandImm_C(opcode, APSR_C,
9767                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9768       break;
9769     default:
9770       return false;
9771     }
9772 
9773     // Read the first operand.
9774     uint32_t val1 = ReadCoreReg(Rn, &success);
9775     if (!success)
9776       return false;
9777 
9778     uint32_t result = val1 ^ imm32;
9779 
9780     EmulateInstruction::Context context;
9781     context.type = EmulateInstruction::eContextImmediate;
9782     context.SetNoArgs();
9783 
9784     if (!WriteFlags(context, result, carry))
9785       return false;
9786   }
9787   return true;
9788 }
9789 
9790 // Test Equivalence (register) performs a bitwise exclusive OR operation on a
9791 // register value and an optionally-shifted register value.  It updates the
9792 // condition flags based on the result, and discards the result.
EmulateTEQReg(const uint32_t opcode,const ARMEncoding encoding)9793 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9794                                           const ARMEncoding encoding) {
9795 #if 0
9796     // ARM pseudo code...
9797     if ConditionPassed() then
9798         EncodingSpecificOperations();
9799         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9800         result = R[n] EOR shifted;
9801         APSR.N = result<31>;
9802         APSR.Z = IsZeroBit(result);
9803         APSR.C = carry;
9804         // APSR.V unchanged
9805 #endif
9806 
9807   bool success = false;
9808 
9809   if (ConditionPassed(opcode)) {
9810     uint32_t Rn, Rm;
9811     ARM_ShifterType shift_t;
9812     uint32_t shift_n; // the shift applied to the value read from Rm
9813     uint32_t carry;
9814     switch (encoding) {
9815     case eEncodingT1:
9816       Rn = Bits32(opcode, 19, 16);
9817       Rm = Bits32(opcode, 3, 0);
9818       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9819       if (BadReg(Rn) || BadReg(Rm))
9820         return false;
9821       break;
9822     case eEncodingA1:
9823       Rn = Bits32(opcode, 19, 16);
9824       Rm = Bits32(opcode, 3, 0);
9825       shift_n = DecodeImmShiftARM(opcode, shift_t);
9826       break;
9827     default:
9828       return false;
9829     }
9830 
9831     // Read the first operand.
9832     uint32_t val1 = ReadCoreReg(Rn, &success);
9833     if (!success)
9834       return false;
9835 
9836     // Read the second operand.
9837     uint32_t val2 = ReadCoreReg(Rm, &success);
9838     if (!success)
9839       return false;
9840 
9841     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9842     if (!success)
9843       return false;
9844     uint32_t result = val1 ^ shifted;
9845 
9846     EmulateInstruction::Context context;
9847     context.type = EmulateInstruction::eContextImmediate;
9848     context.SetNoArgs();
9849 
9850     if (!WriteFlags(context, result, carry))
9851       return false;
9852   }
9853   return true;
9854 }
9855 
9856 // Test (immediate) performs a bitwise AND operation on a register value and an
9857 // immediate value. It updates the condition flags based on the result, and
9858 // discards the result.
EmulateTSTImm(const uint32_t opcode,const ARMEncoding encoding)9859 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9860                                           const ARMEncoding encoding) {
9861 #if 0
9862     // ARM pseudo code...
9863     if ConditionPassed() then
9864         EncodingSpecificOperations();
9865         result = R[n] AND imm32;
9866         APSR.N = result<31>;
9867         APSR.Z = IsZeroBit(result);
9868         APSR.C = carry;
9869         // APSR.V unchanged
9870 #endif
9871 
9872   bool success = false;
9873 
9874   if (ConditionPassed(opcode)) {
9875     uint32_t Rn;
9876     uint32_t
9877         imm32; // the immediate value to be ANDed to the value obtained from Rn
9878     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9879     switch (encoding) {
9880     case eEncodingT1:
9881       Rn = Bits32(opcode, 19, 16);
9882       imm32 = ThumbExpandImm_C(
9883           opcode, APSR_C,
9884           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9885       if (BadReg(Rn))
9886         return false;
9887       break;
9888     case eEncodingA1:
9889       Rn = Bits32(opcode, 19, 16);
9890       imm32 =
9891           ARMExpandImm_C(opcode, APSR_C,
9892                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9893       break;
9894     default:
9895       return false;
9896     }
9897 
9898     // Read the first operand.
9899     uint32_t val1 = ReadCoreReg(Rn, &success);
9900     if (!success)
9901       return false;
9902 
9903     uint32_t result = val1 & imm32;
9904 
9905     EmulateInstruction::Context context;
9906     context.type = EmulateInstruction::eContextImmediate;
9907     context.SetNoArgs();
9908 
9909     if (!WriteFlags(context, result, carry))
9910       return false;
9911   }
9912   return true;
9913 }
9914 
9915 // Test (register) performs a bitwise AND operation on a register value and an
9916 // optionally-shifted register value. It updates the condition flags based on
9917 // the result, and discards the result.
EmulateTSTReg(const uint32_t opcode,const ARMEncoding encoding)9918 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9919                                           const ARMEncoding encoding) {
9920 #if 0
9921     // ARM pseudo code...
9922     if ConditionPassed() then
9923         EncodingSpecificOperations();
9924         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9925         result = R[n] AND shifted;
9926         APSR.N = result<31>;
9927         APSR.Z = IsZeroBit(result);
9928         APSR.C = carry;
9929         // APSR.V unchanged
9930 #endif
9931 
9932   bool success = false;
9933 
9934   if (ConditionPassed(opcode)) {
9935     uint32_t Rn, Rm;
9936     ARM_ShifterType shift_t;
9937     uint32_t shift_n; // the shift applied to the value read from Rm
9938     uint32_t carry;
9939     switch (encoding) {
9940     case eEncodingT1:
9941       Rn = Bits32(opcode, 2, 0);
9942       Rm = Bits32(opcode, 5, 3);
9943       shift_t = SRType_LSL;
9944       shift_n = 0;
9945       break;
9946     case eEncodingT2:
9947       Rn = Bits32(opcode, 19, 16);
9948       Rm = Bits32(opcode, 3, 0);
9949       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9950       if (BadReg(Rn) || BadReg(Rm))
9951         return false;
9952       break;
9953     case eEncodingA1:
9954       Rn = Bits32(opcode, 19, 16);
9955       Rm = Bits32(opcode, 3, 0);
9956       shift_n = DecodeImmShiftARM(opcode, shift_t);
9957       break;
9958     default:
9959       return false;
9960     }
9961 
9962     // Read the first operand.
9963     uint32_t val1 = ReadCoreReg(Rn, &success);
9964     if (!success)
9965       return false;
9966 
9967     // Read the second operand.
9968     uint32_t val2 = ReadCoreReg(Rm, &success);
9969     if (!success)
9970       return false;
9971 
9972     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9973     if (!success)
9974       return false;
9975     uint32_t result = val1 & shifted;
9976 
9977     EmulateInstruction::Context context;
9978     context.type = EmulateInstruction::eContextImmediate;
9979     context.SetNoArgs();
9980 
9981     if (!WriteFlags(context, result, carry))
9982       return false;
9983   }
9984   return true;
9985 }
9986 
9987 // A8.6.216 SUB (SP minus register)
EmulateSUBSPReg(const uint32_t opcode,const ARMEncoding encoding)9988 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
9989                                             const ARMEncoding encoding) {
9990 #if 0
9991     if ConditionPassed() then
9992         EncodingSpecificOperations();
9993         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9994         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9995         if d == 15 then // Can only occur for ARM encoding
9996             ALUWritePC(result); // setflags is always FALSE here
9997         else
9998             R[d] = result;
9999             if setflags then
10000                 APSR.N = result<31>;
10001                 APSR.Z = IsZeroBit(result);
10002                 APSR.C = carry;
10003                 APSR.V = overflow;
10004 #endif
10005 
10006   bool success = false;
10007 
10008   if (ConditionPassed(opcode)) {
10009     uint32_t d;
10010     uint32_t m;
10011     bool setflags;
10012     ARM_ShifterType shift_t;
10013     uint32_t shift_n;
10014 
10015     switch (encoding) {
10016     case eEncodingT1:
10017       // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10018       d = Bits32(opcode, 11, 8);
10019       m = Bits32(opcode, 3, 0);
10020       setflags = BitIsSet(opcode, 20);
10021 
10022       // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10023       shift_n = DecodeImmShiftThumb(opcode, shift_t);
10024 
10025       // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10026       // UNPREDICTABLE;
10027       if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10028         return false;
10029 
10030       // if d == 15 || BadReg(m) then UNPREDICTABLE;
10031       if ((d == 15) || BadReg(m))
10032         return false;
10033       break;
10034 
10035     case eEncodingA1:
10036       // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10037       d = Bits32(opcode, 15, 12);
10038       m = Bits32(opcode, 3, 0);
10039       setflags = BitIsSet(opcode, 20);
10040 
10041       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10042       // instructions;
10043       if (d == 15 && setflags)
10044         EmulateSUBSPcLrEtc(opcode, encoding);
10045 
10046       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10047       shift_n = DecodeImmShiftARM(opcode, shift_t);
10048       break;
10049 
10050     default:
10051       return false;
10052     }
10053 
10054     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10055     uint32_t Rm = ReadCoreReg(m, &success);
10056     if (!success)
10057       return false;
10058 
10059     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10060     if (!success)
10061       return false;
10062 
10063     // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10064     uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10065     if (!success)
10066       return false;
10067 
10068     AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10069 
10070     EmulateInstruction::Context context;
10071     context.type = eContextArithmetic;
10072     std::optional<RegisterInfo> sp_reg =
10073         GetRegisterInfo(eRegisterKindDWARF, dwarf_sp);
10074     std::optional<RegisterInfo> dwarf_reg =
10075         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10076     context.SetRegisterRegisterOperands(*sp_reg, *dwarf_reg);
10077 
10078     if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10079                                    res.carry_out, res.overflow))
10080       return false;
10081   }
10082   return true;
10083 }
10084 
10085 // A8.6.7 ADD (register-shifted register)
EmulateADDRegShift(const uint32_t opcode,const ARMEncoding encoding)10086 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10087                                                const ARMEncoding encoding) {
10088 #if 0
10089     if ConditionPassed() then
10090         EncodingSpecificOperations();
10091         shift_n = UInt(R[s]<7:0>);
10092         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10093         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10094         R[d] = result;
10095         if setflags then
10096             APSR.N = result<31>;
10097             APSR.Z = IsZeroBit(result);
10098             APSR.C = carry;
10099             APSR.V = overflow;
10100 #endif
10101 
10102   bool success = false;
10103 
10104   if (ConditionPassed(opcode)) {
10105     uint32_t d;
10106     uint32_t n;
10107     uint32_t m;
10108     uint32_t s;
10109     bool setflags;
10110     ARM_ShifterType shift_t;
10111 
10112     switch (encoding) {
10113     case eEncodingA1:
10114       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10115       d = Bits32(opcode, 15, 12);
10116       n = Bits32(opcode, 19, 16);
10117       m = Bits32(opcode, 3, 0);
10118       s = Bits32(opcode, 11, 8);
10119 
10120       // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10121       setflags = BitIsSet(opcode, 20);
10122       shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10123 
10124       // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10125       if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10126         return false;
10127       break;
10128 
10129     default:
10130       return false;
10131     }
10132 
10133     // shift_n = UInt(R[s]<7:0>);
10134     uint32_t Rs = ReadCoreReg(s, &success);
10135     if (!success)
10136       return false;
10137 
10138     uint32_t shift_n = Bits32(Rs, 7, 0);
10139 
10140     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10141     uint32_t Rm = ReadCoreReg(m, &success);
10142     if (!success)
10143       return false;
10144 
10145     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10146     if (!success)
10147       return false;
10148 
10149     // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10150     uint32_t Rn = ReadCoreReg(n, &success);
10151     if (!success)
10152       return false;
10153 
10154     AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10155 
10156     // R[d] = result;
10157     EmulateInstruction::Context context;
10158     context.type = eContextArithmetic;
10159     std::optional<RegisterInfo> reg_n =
10160         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10161     std::optional<RegisterInfo> reg_m =
10162         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10163 
10164     context.SetRegisterRegisterOperands(*reg_n, *reg_m);
10165 
10166     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10167                                res.result))
10168       return false;
10169 
10170     // if setflags then
10171     // APSR.N = result<31>;
10172     // APSR.Z = IsZeroBit(result);
10173     // APSR.C = carry;
10174     // APSR.V = overflow;
10175     if (setflags)
10176       return WriteFlags(context, res.result, res.carry_out, res.overflow);
10177   }
10178   return true;
10179 }
10180 
10181 // A8.6.213 SUB (register)
EmulateSUBReg(const uint32_t opcode,const ARMEncoding encoding)10182 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10183                                           const ARMEncoding encoding) {
10184 #if 0
10185     if ConditionPassed() then
10186         EncodingSpecificOperations();
10187         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10188         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10189         if d == 15 then // Can only occur for ARM encoding
10190             ALUWritePC(result); // setflags is always FALSE here
10191         else
10192             R[d] = result;
10193             if setflags then
10194                 APSR.N = result<31>;
10195                 APSR.Z = IsZeroBit(result);
10196                 APSR.C = carry;
10197                 APSR.V = overflow;
10198 #endif
10199 
10200   bool success = false;
10201 
10202   if (ConditionPassed(opcode)) {
10203     uint32_t d;
10204     uint32_t n;
10205     uint32_t m;
10206     bool setflags;
10207     ARM_ShifterType shift_t;
10208     uint32_t shift_n;
10209 
10210     switch (encoding) {
10211     case eEncodingT1:
10212       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10213       d = Bits32(opcode, 2, 0);
10214       n = Bits32(opcode, 5, 3);
10215       m = Bits32(opcode, 8, 6);
10216       setflags = !InITBlock();
10217 
10218       // (shift_t, shift_n) = (SRType_LSL, 0);
10219       shift_t = SRType_LSL;
10220       shift_n = 0;
10221 
10222       break;
10223 
10224     case eEncodingT2:
10225       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10226       d = Bits32(opcode, 11, 8);
10227       n = Bits32(opcode, 19, 16);
10228       m = Bits32(opcode, 3, 0);
10229       setflags = BitIsSet(opcode, 20);
10230 
10231       // if Rd == "1111" && S == "1" then SEE CMP (register);
10232       if (d == 15 && setflags == 1)
10233         return EmulateCMPImm(opcode, eEncodingT3);
10234 
10235       // if Rn == "1101" then SEE SUB (SP minus register);
10236       if (n == 13)
10237         return EmulateSUBSPReg(opcode, eEncodingT1);
10238 
10239       // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10240       shift_n = DecodeImmShiftThumb(opcode, shift_t);
10241 
10242       // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10243       // UNPREDICTABLE;
10244       if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10245           BadReg(m))
10246         return false;
10247 
10248       break;
10249 
10250     case eEncodingA1:
10251       // if Rn == '1101' then SEE SUB (SP minus register);
10252       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10253       d = Bits32(opcode, 15, 12);
10254       n = Bits32(opcode, 19, 16);
10255       m = Bits32(opcode, 3, 0);
10256       setflags = BitIsSet(opcode, 20);
10257 
10258       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10259       // instructions;
10260       if ((d == 15) && setflags)
10261         EmulateSUBSPcLrEtc(opcode, encoding);
10262 
10263       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10264       shift_n = DecodeImmShiftARM(opcode, shift_t);
10265 
10266       break;
10267 
10268     default:
10269       return false;
10270     }
10271 
10272     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10273     uint32_t Rm = ReadCoreReg(m, &success);
10274     if (!success)
10275       return false;
10276 
10277     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10278     if (!success)
10279       return false;
10280 
10281     // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10282     uint32_t Rn = ReadCoreReg(n, &success);
10283     if (!success)
10284       return false;
10285 
10286     AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10287 
10288     // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10289     // // setflags is always FALSE here else
10290     // R[d] = result;
10291     // if setflags then
10292     // APSR.N = result<31>;
10293     // APSR.Z = IsZeroBit(result);
10294     // APSR.C = carry;
10295     // APSR.V = overflow;
10296 
10297     EmulateInstruction::Context context;
10298     context.type = eContextArithmetic;
10299     std::optional<RegisterInfo> reg_n =
10300         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10301     std::optional<RegisterInfo> reg_m =
10302         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
10303     context.SetRegisterRegisterOperands(*reg_n, *reg_m);
10304 
10305     if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10306                                    res.carry_out, res.overflow))
10307       return false;
10308   }
10309   return true;
10310 }
10311 
10312 // A8.6.202 STREX
10313 // Store Register Exclusive calculates an address from a base register value
10314 // and an immediate offset, and stores a word from a register to memory if the
10315 // executing processor has exclusive access to the memory addressed.
EmulateSTREX(const uint32_t opcode,const ARMEncoding encoding)10316 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10317                                          const ARMEncoding encoding) {
10318 #if 0
10319     if ConditionPassed() then
10320         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10321         address = R[n] + imm32;
10322         if ExclusiveMonitorsPass(address,4) then
10323             MemA[address,4] = R[t];
10324             R[d] = 0;
10325         else
10326             R[d] = 1;
10327 #endif
10328 
10329   bool success = false;
10330 
10331   if (ConditionPassed(opcode)) {
10332     uint32_t d;
10333     uint32_t t;
10334     uint32_t n;
10335     uint32_t imm32;
10336     const uint32_t addr_byte_size = GetAddressByteSize();
10337 
10338     switch (encoding) {
10339     case eEncodingT1:
10340       // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10341       // ZeroExtend(imm8:'00',
10342       // 32);
10343       d = Bits32(opcode, 11, 8);
10344       t = Bits32(opcode, 15, 12);
10345       n = Bits32(opcode, 19, 16);
10346       imm32 = Bits32(opcode, 7, 0) << 2;
10347 
10348       // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10349       if (BadReg(d) || BadReg(t) || (n == 15))
10350         return false;
10351 
10352       // if d == n || d == t then UNPREDICTABLE;
10353       if ((d == n) || (d == t))
10354         return false;
10355 
10356       break;
10357 
10358     case eEncodingA1:
10359       // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10360       // offset
10361       d = Bits32(opcode, 15, 12);
10362       t = Bits32(opcode, 3, 0);
10363       n = Bits32(opcode, 19, 16);
10364       imm32 = 0;
10365 
10366       // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10367       if ((d == 15) || (t == 15) || (n == 15))
10368         return false;
10369 
10370       // if d == n || d == t then UNPREDICTABLE;
10371       if ((d == n) || (d == t))
10372         return false;
10373 
10374       break;
10375 
10376     default:
10377       return false;
10378     }
10379 
10380     // address = R[n] + imm32;
10381     uint32_t Rn = ReadCoreReg(n, &success);
10382     if (!success)
10383       return false;
10384 
10385     addr_t address = Rn + imm32;
10386 
10387     std::optional<RegisterInfo> base_reg =
10388         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10389     std::optional<RegisterInfo> data_reg =
10390         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10391     EmulateInstruction::Context context;
10392     context.type = eContextRegisterStore;
10393     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, imm32);
10394 
10395     // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10396     // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10397     // will say this
10398     //                                                         always return
10399     //                                                         true.
10400     if (true) {
10401       // MemA[address,4] = R[t];
10402       uint32_t Rt =
10403           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10404       if (!success)
10405         return false;
10406 
10407       if (!MemAWrite(context, address, Rt, addr_byte_size))
10408         return false;
10409 
10410       // R[d] = 0;
10411       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10412         return false;
10413     }
10414 #if 0  // unreachable because if true
10415         else
10416         {
10417             // R[d] = 1;
10418             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10419                 return false;
10420         }
10421 #endif // unreachable because if true
10422   }
10423   return true;
10424 }
10425 
10426 // A8.6.197 STRB (immediate, ARM)
EmulateSTRBImmARM(const uint32_t opcode,const ARMEncoding encoding)10427 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10428                                               const ARMEncoding encoding) {
10429 #if 0
10430     if ConditionPassed() then
10431         EncodingSpecificOperations();
10432         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10433         address = if index then offset_addr else R[n];
10434         MemU[address,1] = R[t]<7:0>;
10435         if wback then R[n] = offset_addr;
10436 #endif
10437 
10438   bool success = false;
10439 
10440   if (ConditionPassed(opcode)) {
10441     uint32_t t;
10442     uint32_t n;
10443     uint32_t imm32;
10444     bool index;
10445     bool add;
10446     bool wback;
10447 
10448     switch (encoding) {
10449     case eEncodingA1:
10450       // if P == '0' && W == '1' then SEE STRBT;
10451       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10452       t = Bits32(opcode, 15, 12);
10453       n = Bits32(opcode, 19, 16);
10454       imm32 = Bits32(opcode, 11, 0);
10455 
10456       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10457       index = BitIsSet(opcode, 24);
10458       add = BitIsSet(opcode, 23);
10459       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10460 
10461       // if t == 15 then UNPREDICTABLE;
10462       if (t == 15)
10463         return false;
10464 
10465       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10466       if (wback && ((n == 15) || (n == t)))
10467         return false;
10468 
10469       break;
10470 
10471     default:
10472       return false;
10473     }
10474 
10475     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10476     uint32_t Rn = ReadCoreReg(n, &success);
10477     if (!success)
10478       return false;
10479 
10480     addr_t offset_addr;
10481     if (add)
10482       offset_addr = Rn + imm32;
10483     else
10484       offset_addr = Rn - imm32;
10485 
10486     // address = if index then offset_addr else R[n];
10487     addr_t address;
10488     if (index)
10489       address = offset_addr;
10490     else
10491       address = Rn;
10492 
10493     // MemU[address,1] = R[t]<7:0>;
10494     uint32_t Rt = ReadCoreReg(t, &success);
10495     if (!success)
10496       return false;
10497 
10498     std::optional<RegisterInfo> base_reg =
10499         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10500     std::optional<RegisterInfo> data_reg =
10501         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10502     EmulateInstruction::Context context;
10503     context.type = eContextRegisterStore;
10504     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
10505 
10506     if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10507       return false;
10508 
10509     // if wback then R[n] = offset_addr;
10510     if (wback) {
10511       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10512                                  offset_addr))
10513         return false;
10514     }
10515   }
10516   return true;
10517 }
10518 
10519 // A8.6.194 STR (immediate, ARM)
EmulateSTRImmARM(const uint32_t opcode,const ARMEncoding encoding)10520 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10521                                              const ARMEncoding encoding) {
10522 #if 0
10523     if ConditionPassed() then
10524         EncodingSpecificOperations();
10525         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10526         address = if index then offset_addr else R[n];
10527         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10528         if wback then R[n] = offset_addr;
10529 #endif
10530 
10531   bool success = false;
10532 
10533   if (ConditionPassed(opcode)) {
10534     uint32_t t;
10535     uint32_t n;
10536     uint32_t imm32;
10537     bool index;
10538     bool add;
10539     bool wback;
10540 
10541     const uint32_t addr_byte_size = GetAddressByteSize();
10542 
10543     switch (encoding) {
10544     case eEncodingA1:
10545       // if P == '0' && W == '1' then SEE STRT;
10546       // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10547       // '000000000100' then SEE PUSH;
10548       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10549       t = Bits32(opcode, 15, 12);
10550       n = Bits32(opcode, 19, 16);
10551       imm32 = Bits32(opcode, 11, 0);
10552 
10553       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10554       index = BitIsSet(opcode, 24);
10555       add = BitIsSet(opcode, 23);
10556       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10557 
10558       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10559       if (wback && ((n == 15) || (n == t)))
10560         return false;
10561 
10562       break;
10563 
10564     default:
10565       return false;
10566     }
10567 
10568     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10569     uint32_t Rn = ReadCoreReg(n, &success);
10570     if (!success)
10571       return false;
10572 
10573     addr_t offset_addr;
10574     if (add)
10575       offset_addr = Rn + imm32;
10576     else
10577       offset_addr = Rn - imm32;
10578 
10579     // address = if index then offset_addr else R[n];
10580     addr_t address;
10581     if (index)
10582       address = offset_addr;
10583     else
10584       address = Rn;
10585 
10586     std::optional<RegisterInfo> base_reg =
10587         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10588     std::optional<RegisterInfo> data_reg =
10589         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
10590     EmulateInstruction::Context context;
10591     context.type = eContextRegisterStore;
10592     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
10593 
10594     // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10595     uint32_t Rt = ReadCoreReg(t, &success);
10596     if (!success)
10597       return false;
10598 
10599     if (t == 15) {
10600       uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10601       if (!success)
10602         return false;
10603 
10604       if (!MemUWrite(context, address, pc_value, addr_byte_size))
10605         return false;
10606     } else {
10607       if (!MemUWrite(context, address, Rt, addr_byte_size))
10608         return false;
10609     }
10610 
10611     // if wback then R[n] = offset_addr;
10612     if (wback) {
10613       context.type = eContextAdjustBaseRegister;
10614       context.SetImmediate(offset_addr);
10615 
10616       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10617                                  offset_addr))
10618         return false;
10619     }
10620   }
10621   return true;
10622 }
10623 
10624 // A8.6.66 LDRD (immediate)
10625 // Load Register Dual (immediate) calculates an address from a base register
10626 // value and an immediate offset, loads two words from memory, and writes them
10627 // to two registers.  It can use offset, post-indexed, or pre-indexed
10628 // addressing.
EmulateLDRDImmediate(const uint32_t opcode,const ARMEncoding encoding)10629 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10630                                                  const ARMEncoding encoding) {
10631 #if 0
10632     if ConditionPassed() then
10633         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10634         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10635         address = if index then offset_addr else R[n];
10636         R[t] = MemA[address,4];
10637         R[t2] = MemA[address+4,4];
10638         if wback then R[n] = offset_addr;
10639 #endif
10640 
10641   bool success = false;
10642 
10643   if (ConditionPassed(opcode)) {
10644     uint32_t t;
10645     uint32_t t2;
10646     uint32_t n;
10647     uint32_t imm32;
10648     bool index;
10649     bool add;
10650     bool wback;
10651 
10652     switch (encoding) {
10653     case eEncodingT1:
10654       // if P == '0' && W == '0' then SEE 'Related encodings';
10655       // if Rn == '1111' then SEE LDRD (literal);
10656       // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10657       // ZeroExtend(imm8:'00', 32);
10658       t = Bits32(opcode, 15, 12);
10659       t2 = Bits32(opcode, 11, 8);
10660       n = Bits32(opcode, 19, 16);
10661       imm32 = Bits32(opcode, 7, 0) << 2;
10662 
10663       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10664       index = BitIsSet(opcode, 24);
10665       add = BitIsSet(opcode, 23);
10666       wback = BitIsSet(opcode, 21);
10667 
10668       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10669       if (wback && ((n == t) || (n == t2)))
10670         return false;
10671 
10672       // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10673       if (BadReg(t) || BadReg(t2) || (t == t2))
10674         return false;
10675 
10676       break;
10677 
10678     case eEncodingA1:
10679       // if Rn == '1111' then SEE LDRD (literal);
10680       // if Rt<0> == '1' then UNPREDICTABLE;
10681       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10682       // 32);
10683       t = Bits32(opcode, 15, 12);
10684       if (BitIsSet(t, 0))
10685         return false;
10686       t2 = t + 1;
10687       n = Bits32(opcode, 19, 16);
10688       imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10689 
10690       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10691       index = BitIsSet(opcode, 24);
10692       add = BitIsSet(opcode, 23);
10693       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10694 
10695       // if P == '0' && W == '1' then UNPREDICTABLE;
10696       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10697         return false;
10698 
10699       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10700       if (wback && ((n == t) || (n == t2)))
10701         return false;
10702 
10703       // if t2 == 15 then UNPREDICTABLE;
10704       if (t2 == 15)
10705         return false;
10706 
10707       break;
10708 
10709     default:
10710       return false;
10711     }
10712 
10713     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10714     uint32_t Rn = ReadCoreReg(n, &success);
10715     if (!success)
10716       return false;
10717 
10718     addr_t offset_addr;
10719     if (add)
10720       offset_addr = Rn + imm32;
10721     else
10722       offset_addr = Rn - imm32;
10723 
10724     // address = if index then offset_addr else R[n];
10725     addr_t address;
10726     if (index)
10727       address = offset_addr;
10728     else
10729       address = Rn;
10730 
10731     // R[t] = MemA[address,4];
10732 
10733     EmulateInstruction::Context context;
10734     if (n == 13)
10735       context.type = eContextPopRegisterOffStack;
10736     else
10737       context.type = eContextRegisterLoad;
10738     context.SetAddress(address);
10739 
10740     const uint32_t addr_byte_size = GetAddressByteSize();
10741     uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10742     if (!success)
10743       return false;
10744 
10745     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10746       return false;
10747 
10748     // R[t2] = MemA[address+4,4];
10749     context.SetAddress(address + 4);
10750     data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10751     if (!success)
10752       return false;
10753 
10754     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10755                                data))
10756       return false;
10757 
10758     // if wback then R[n] = offset_addr;
10759     if (wback) {
10760       context.type = eContextAdjustBaseRegister;
10761       context.SetAddress(offset_addr);
10762 
10763       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10764                                  offset_addr))
10765         return false;
10766     }
10767   }
10768   return true;
10769 }
10770 
10771 // A8.6.68 LDRD (register)
10772 // Load Register Dual (register) calculates an address from a base register
10773 // value and a register offset, loads two words from memory, and writes them to
10774 // two registers.  It can use offset, post-indexed or pre-indexed addressing.
EmulateLDRDRegister(const uint32_t opcode,const ARMEncoding encoding)10775 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10776                                                 const ARMEncoding encoding) {
10777 #if 0
10778     if ConditionPassed() then
10779         EncodingSpecificOperations();
10780         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10781         address = if index then offset_addr else R[n];
10782         R[t] = MemA[address,4];
10783         R[t2] = MemA[address+4,4];
10784         if wback then R[n] = offset_addr;
10785 #endif
10786 
10787   bool success = false;
10788 
10789   if (ConditionPassed(opcode)) {
10790     uint32_t t;
10791     uint32_t t2;
10792     uint32_t n;
10793     uint32_t m;
10794     bool index;
10795     bool add;
10796     bool wback;
10797 
10798     switch (encoding) {
10799     case eEncodingA1:
10800       // if Rt<0> == '1' then UNPREDICTABLE;
10801       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10802       t = Bits32(opcode, 15, 12);
10803       if (BitIsSet(t, 0))
10804         return false;
10805       t2 = t + 1;
10806       n = Bits32(opcode, 19, 16);
10807       m = Bits32(opcode, 3, 0);
10808 
10809       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10810       index = BitIsSet(opcode, 24);
10811       add = BitIsSet(opcode, 23);
10812       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10813 
10814       // if P == '0' && W == '1' then UNPREDICTABLE;
10815       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10816         return false;
10817 
10818       // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10819       if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10820         return false;
10821 
10822       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10823       if (wback && ((n == 15) || (n == t) || (n == t2)))
10824         return false;
10825 
10826       // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10827       if ((ArchVersion() < 6) && wback && (m == n))
10828         return false;
10829       break;
10830 
10831     default:
10832       return false;
10833     }
10834 
10835     uint32_t Rn = ReadCoreReg(n, &success);
10836     if (!success)
10837       return false;
10838 
10839     uint32_t Rm = ReadCoreReg(m, &success);
10840     if (!success)
10841       return false;
10842 
10843     // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10844     addr_t offset_addr;
10845     if (add)
10846       offset_addr = Rn + Rm;
10847     else
10848       offset_addr = Rn - Rm;
10849 
10850     // address = if index then offset_addr else R[n];
10851     addr_t address;
10852     if (index)
10853       address = offset_addr;
10854     else
10855       address = Rn;
10856 
10857     EmulateInstruction::Context context;
10858     if (n == 13)
10859       context.type = eContextPopRegisterOffStack;
10860     else
10861       context.type = eContextRegisterLoad;
10862     context.SetAddress(address);
10863 
10864     // R[t] = MemA[address,4];
10865     const uint32_t addr_byte_size = GetAddressByteSize();
10866     uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10867     if (!success)
10868       return false;
10869 
10870     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10871       return false;
10872 
10873     // R[t2] = MemA[address+4,4];
10874 
10875     data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10876     if (!success)
10877       return false;
10878 
10879     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10880                                data))
10881       return false;
10882 
10883     // if wback then R[n] = offset_addr;
10884     if (wback) {
10885       context.type = eContextAdjustBaseRegister;
10886       context.SetAddress(offset_addr);
10887 
10888       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10889                                  offset_addr))
10890         return false;
10891     }
10892   }
10893   return true;
10894 }
10895 
10896 // A8.6.200 STRD (immediate)
10897 // Store Register Dual (immediate) calculates an address from a base register
10898 // value and an immediate offset, and stores two words from two registers to
10899 // memory.  It can use offset, post-indexed, or pre-indexed addressing.
EmulateSTRDImm(const uint32_t opcode,const ARMEncoding encoding)10900 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10901                                            const ARMEncoding encoding) {
10902 #if 0
10903     if ConditionPassed() then
10904         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10905         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10906         address = if index then offset_addr else R[n];
10907         MemA[address,4] = R[t];
10908         MemA[address+4,4] = R[t2];
10909         if wback then R[n] = offset_addr;
10910 #endif
10911 
10912   bool success = false;
10913 
10914   if (ConditionPassed(opcode)) {
10915     uint32_t t;
10916     uint32_t t2;
10917     uint32_t n;
10918     uint32_t imm32;
10919     bool index;
10920     bool add;
10921     bool wback;
10922 
10923     switch (encoding) {
10924     case eEncodingT1:
10925       // if P == '0' && W == '0' then SEE 'Related encodings';
10926       // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10927       // ZeroExtend(imm8:'00', 32);
10928       t = Bits32(opcode, 15, 12);
10929       t2 = Bits32(opcode, 11, 8);
10930       n = Bits32(opcode, 19, 16);
10931       imm32 = Bits32(opcode, 7, 0) << 2;
10932 
10933       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10934       index = BitIsSet(opcode, 24);
10935       add = BitIsSet(opcode, 23);
10936       wback = BitIsSet(opcode, 21);
10937 
10938       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10939       if (wback && ((n == t) || (n == t2)))
10940         return false;
10941 
10942       // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10943       if ((n == 15) || BadReg(t) || BadReg(t2))
10944         return false;
10945 
10946       break;
10947 
10948     case eEncodingA1:
10949       // if Rt<0> == '1' then UNPREDICTABLE;
10950       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10951       // 32);
10952       t = Bits32(opcode, 15, 12);
10953       if (BitIsSet(t, 0))
10954         return false;
10955 
10956       t2 = t + 1;
10957       n = Bits32(opcode, 19, 16);
10958       imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10959 
10960       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10961       index = BitIsSet(opcode, 24);
10962       add = BitIsSet(opcode, 23);
10963       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10964 
10965       // if P == '0' && W == '1' then UNPREDICTABLE;
10966       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10967         return false;
10968 
10969       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10970       if (wback && ((n == 15) || (n == t) || (n == t2)))
10971         return false;
10972 
10973       // if t2 == 15 then UNPREDICTABLE;
10974       if (t2 == 15)
10975         return false;
10976 
10977       break;
10978 
10979     default:
10980       return false;
10981     }
10982 
10983     std::optional<RegisterInfo> base_reg =
10984         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
10985 
10986     uint32_t Rn = ReadCoreReg(n, &success);
10987     if (!success)
10988       return false;
10989 
10990     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10991     addr_t offset_addr;
10992     if (add)
10993       offset_addr = Rn + imm32;
10994     else
10995       offset_addr = Rn - imm32;
10996 
10997     // address = if index then offset_addr else R[n];
10998     addr_t address;
10999     if (index)
11000       address = offset_addr;
11001     else
11002       address = Rn;
11003 
11004     // MemA[address,4] = R[t];
11005     std::optional<RegisterInfo> data_reg =
11006         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
11007 
11008     uint32_t data = ReadCoreReg(t, &success);
11009     if (!success)
11010       return false;
11011 
11012     EmulateInstruction::Context context;
11013     if (n == 13)
11014       context.type = eContextPushRegisterOnStack;
11015     else
11016       context.type = eContextRegisterStore;
11017     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
11018 
11019     const uint32_t addr_byte_size = GetAddressByteSize();
11020 
11021     if (!MemAWrite(context, address, data, addr_byte_size))
11022       return false;
11023 
11024     // MemA[address+4,4] = R[t2];
11025     data_reg = GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2);
11026     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11027                                             (address + 4) - Rn);
11028 
11029     data = ReadCoreReg(t2, &success);
11030     if (!success)
11031       return false;
11032 
11033     if (!MemAWrite(context, address + 4, data, addr_byte_size))
11034       return false;
11035 
11036     // if wback then R[n] = offset_addr;
11037     if (wback) {
11038       if (n == 13)
11039         context.type = eContextAdjustStackPointer;
11040       else
11041         context.type = eContextAdjustBaseRegister;
11042       context.SetAddress(offset_addr);
11043 
11044       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11045                                  offset_addr))
11046         return false;
11047     }
11048   }
11049   return true;
11050 }
11051 
11052 // A8.6.201 STRD (register)
EmulateSTRDReg(const uint32_t opcode,const ARMEncoding encoding)11053 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11054                                            const ARMEncoding encoding) {
11055 #if 0
11056     if ConditionPassed() then
11057         EncodingSpecificOperations();
11058         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11059         address = if index then offset_addr else R[n];
11060         MemA[address,4] = R[t];
11061         MemA[address+4,4] = R[t2];
11062         if wback then R[n] = offset_addr;
11063 #endif
11064 
11065   bool success = false;
11066 
11067   if (ConditionPassed(opcode)) {
11068     uint32_t t;
11069     uint32_t t2;
11070     uint32_t n;
11071     uint32_t m;
11072     bool index;
11073     bool add;
11074     bool wback;
11075 
11076     switch (encoding) {
11077     case eEncodingA1:
11078       // if Rt<0> == '1' then UNPREDICTABLE;
11079       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11080       t = Bits32(opcode, 15, 12);
11081       if (BitIsSet(t, 0))
11082         return false;
11083 
11084       t2 = t + 1;
11085       n = Bits32(opcode, 19, 16);
11086       m = Bits32(opcode, 3, 0);
11087 
11088       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11089       index = BitIsSet(opcode, 24);
11090       add = BitIsSet(opcode, 23);
11091       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11092 
11093       // if P == '0' && W == '1' then UNPREDICTABLE;
11094       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11095         return false;
11096 
11097       // if t2 == 15 || m == 15 then UNPREDICTABLE;
11098       if ((t2 == 15) || (m == 15))
11099         return false;
11100 
11101       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11102       if (wback && ((n == 15) || (n == t) || (n == t2)))
11103         return false;
11104 
11105       // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11106       if ((ArchVersion() < 6) && wback && (m == n))
11107         return false;
11108 
11109       break;
11110 
11111     default:
11112       return false;
11113     }
11114 
11115     uint32_t Rn = ReadCoreReg(n, &success);
11116     if (!success)
11117       return false;
11118 
11119     uint32_t Rm = ReadCoreReg(m, &success);
11120     if (!success)
11121       return false;
11122 
11123     // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11124     addr_t offset_addr;
11125     if (add)
11126       offset_addr = Rn + Rm;
11127     else
11128       offset_addr = Rn - Rm;
11129 
11130     // address = if index then offset_addr else R[n];
11131     addr_t address;
11132     if (index)
11133       address = offset_addr;
11134     else
11135       address = Rn;
11136     // MemA[address,4] = R[t];
11137     uint32_t Rt = ReadCoreReg(t, &success);
11138     if (!success)
11139       return false;
11140 
11141     EmulateInstruction::Context context;
11142     if (t == 13)
11143       context.type = eContextPushRegisterOnStack;
11144     else
11145       context.type = eContextRegisterStore;
11146 
11147     std::optional<RegisterInfo> base_reg =
11148         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11149     std::optional<RegisterInfo> offset_reg =
11150         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m);
11151     std::optional<RegisterInfo> data_reg =
11152         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t);
11153     context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
11154                                                     *data_reg);
11155 
11156     const uint32_t addr_byte_size = GetAddressByteSize();
11157 
11158     if (!MemAWrite(context, address, Rt, addr_byte_size))
11159       return false;
11160 
11161     // MemA[address+4,4] = R[t2];
11162     uint32_t Rt2 = ReadCoreReg(t2, &success);
11163     if (!success)
11164       return false;
11165 
11166     data_reg = GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2);
11167 
11168     context.SetRegisterToRegisterPlusIndirectOffset(*base_reg, *offset_reg,
11169                                                     *data_reg);
11170 
11171     if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11172       return false;
11173 
11174     // if wback then R[n] = offset_addr;
11175     if (wback) {
11176       context.type = eContextAdjustBaseRegister;
11177       context.SetAddress(offset_addr);
11178 
11179       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11180                                  offset_addr))
11181         return false;
11182     }
11183   }
11184   return true;
11185 }
11186 
11187 // A8.6.319 VLDM
11188 // Vector Load Multiple loads multiple extension registers from consecutive
11189 // memory locations using an address from an ARM core register.
EmulateVLDM(const uint32_t opcode,const ARMEncoding encoding)11190 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11191                                         const ARMEncoding encoding) {
11192 #if 0
11193     if ConditionPassed() then
11194         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11195         address = if add then R[n] else R[n]-imm32;
11196         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11197         for r = 0 to regs-1
11198             if single_regs then
11199                 S[d+r] = MemA[address,4]; address = address+4;
11200             else
11201                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11202                 // Combine the word-aligned words in the correct order for
11203                 // current endianness.
11204                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11205 #endif
11206 
11207   bool success = false;
11208 
11209   if (ConditionPassed(opcode)) {
11210     bool single_regs;
11211     bool add;
11212     bool wback;
11213     uint32_t d;
11214     uint32_t n;
11215     uint32_t imm32;
11216     uint32_t regs;
11217 
11218     switch (encoding) {
11219     case eEncodingT1:
11220     case eEncodingA1:
11221       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11222       // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11223       // if P == '1' && W == '0' then SEE VLDR;
11224       // if P == U && W == '1' then UNDEFINED;
11225       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11226         return false;
11227 
11228       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11229       // !), 101 (DB with !)
11230       // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11231       single_regs = false;
11232       add = BitIsSet(opcode, 23);
11233       wback = BitIsSet(opcode, 21);
11234 
11235       // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11236       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11237       n = Bits32(opcode, 19, 16);
11238       imm32 = Bits32(opcode, 7, 0) << 2;
11239 
11240       // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11241       regs = Bits32(opcode, 7, 0) / 2;
11242 
11243       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11244       // UNPREDICTABLE;
11245       if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11246         return false;
11247 
11248       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11249       if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11250         return false;
11251 
11252       break;
11253 
11254     case eEncodingT2:
11255     case eEncodingA2:
11256       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11257       // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11258       // if P == '1' && W == '0' then SEE VLDR;
11259       // if P == U && W == '1' then UNDEFINED;
11260       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11261         return false;
11262 
11263       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11264       // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11265       // == '1'); d =
11266       // UInt(Vd:D); n = UInt(Rn);
11267       single_regs = true;
11268       add = BitIsSet(opcode, 23);
11269       wback = BitIsSet(opcode, 21);
11270       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11271       n = Bits32(opcode, 19, 16);
11272 
11273       // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11274       imm32 = Bits32(opcode, 7, 0) << 2;
11275       regs = Bits32(opcode, 7, 0);
11276 
11277       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11278       // UNPREDICTABLE;
11279       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11280         return false;
11281 
11282       // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11283       if ((regs == 0) || ((d + regs) > 32))
11284         return false;
11285       break;
11286 
11287     default:
11288       return false;
11289     }
11290 
11291     uint32_t Rn = ReadCoreReg(n, &success);
11292     if (!success)
11293       return false;
11294 
11295     // address = if add then R[n] else R[n]-imm32;
11296     addr_t address;
11297     if (add)
11298       address = Rn;
11299     else
11300       address = Rn - imm32;
11301 
11302     // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11303     EmulateInstruction::Context context;
11304 
11305     if (wback) {
11306       uint32_t value;
11307       if (add)
11308         value = Rn + imm32;
11309       else
11310         value = Rn - imm32;
11311 
11312       context.type = eContextAdjustBaseRegister;
11313       context.SetImmediateSigned(value - Rn);
11314       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11315                                  value))
11316         return false;
11317     }
11318 
11319     const uint32_t addr_byte_size = GetAddressByteSize();
11320     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11321 
11322     context.type = eContextRegisterLoad;
11323 
11324     std::optional<RegisterInfo> base_reg =
11325         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11326 
11327     // for r = 0 to regs-1
11328     for (uint32_t r = 0; r < regs; ++r) {
11329       if (single_regs) {
11330         // S[d+r] = MemA[address,4]; address = address+4;
11331         context.SetRegisterPlusOffset(*base_reg, address - Rn);
11332 
11333         uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11334         if (!success)
11335           return false;
11336 
11337         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11338                                    start_reg + d + r, data))
11339           return false;
11340 
11341         address = address + 4;
11342       } else {
11343         // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11344         // address+8;
11345         context.SetRegisterPlusOffset(*base_reg, address - Rn);
11346         uint32_t word1 =
11347             MemARead(context, address, addr_byte_size, 0, &success);
11348         if (!success)
11349           return false;
11350 
11351         context.SetRegisterPlusOffset(*base_reg, (address + 4) - Rn);
11352         uint32_t word2 =
11353             MemARead(context, address + 4, addr_byte_size, 0, &success);
11354         if (!success)
11355           return false;
11356 
11357         address = address + 8;
11358         // // Combine the word-aligned words in the correct order for current
11359         // endianness.
11360         // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11361         uint64_t data;
11362         if (GetByteOrder() == eByteOrderBig) {
11363           data = word1;
11364           data = (data << 32) | word2;
11365         } else {
11366           data = word2;
11367           data = (data << 32) | word1;
11368         }
11369 
11370         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11371                                    start_reg + d + r, data))
11372           return false;
11373       }
11374     }
11375   }
11376   return true;
11377 }
11378 
11379 // A8.6.399 VSTM
11380 // Vector Store Multiple stores multiple extension registers to consecutive
11381 // memory locations using an address from an
11382 // ARM core register.
EmulateVSTM(const uint32_t opcode,const ARMEncoding encoding)11383 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11384                                         const ARMEncoding encoding) {
11385 #if 0
11386     if ConditionPassed() then
11387         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11388         address = if add then R[n] else R[n]-imm32;
11389         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11390         for r = 0 to regs-1
11391             if single_regs then
11392                 MemA[address,4] = S[d+r]; address = address+4;
11393             else
11394                 // Store as two word-aligned words in the correct order for
11395                 // current endianness.
11396                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11397                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11398                 address = address+8;
11399 #endif
11400 
11401   bool success = false;
11402 
11403   if (ConditionPassed(opcode)) {
11404     bool single_regs;
11405     bool add;
11406     bool wback;
11407     uint32_t d;
11408     uint32_t n;
11409     uint32_t imm32;
11410     uint32_t regs;
11411 
11412     switch (encoding) {
11413     case eEncodingT1:
11414     case eEncodingA1:
11415       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11416       // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11417       // if P == '1' && W == '0' then SEE VSTR;
11418       // if P == U && W == '1' then UNDEFINED;
11419       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11420         return false;
11421 
11422       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11423       // !), 101 (DB with !)
11424       // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11425       single_regs = false;
11426       add = BitIsSet(opcode, 23);
11427       wback = BitIsSet(opcode, 21);
11428 
11429       // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11430       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11431       n = Bits32(opcode, 19, 16);
11432       imm32 = Bits32(opcode, 7, 0) << 2;
11433 
11434       // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11435       regs = Bits32(opcode, 7, 0) / 2;
11436 
11437       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11438       // UNPREDICTABLE;
11439       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11440         return false;
11441 
11442       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11443       if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11444         return false;
11445 
11446       break;
11447 
11448     case eEncodingT2:
11449     case eEncodingA2:
11450       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11451       // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11452       // if P == '1' && W == '0' then SEE VSTR;
11453       // if P == U && W == '1' then UNDEFINED;
11454       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11455         return false;
11456 
11457       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11458       // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11459       // == '1'); d =
11460       // UInt(Vd:D); n = UInt(Rn);
11461       single_regs = true;
11462       add = BitIsSet(opcode, 23);
11463       wback = BitIsSet(opcode, 21);
11464       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11465       n = Bits32(opcode, 19, 16);
11466 
11467       // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11468       imm32 = Bits32(opcode, 7, 0) << 2;
11469       regs = Bits32(opcode, 7, 0);
11470 
11471       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11472       // UNPREDICTABLE;
11473       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11474         return false;
11475 
11476       // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11477       if ((regs == 0) || ((d + regs) > 32))
11478         return false;
11479 
11480       break;
11481 
11482     default:
11483       return false;
11484     }
11485 
11486     std::optional<RegisterInfo> base_reg =
11487         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11488 
11489     uint32_t Rn = ReadCoreReg(n, &success);
11490     if (!success)
11491       return false;
11492 
11493     // address = if add then R[n] else R[n]-imm32;
11494     addr_t address;
11495     if (add)
11496       address = Rn;
11497     else
11498       address = Rn - imm32;
11499 
11500     EmulateInstruction::Context context;
11501     // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11502     if (wback) {
11503       uint32_t value;
11504       if (add)
11505         value = Rn + imm32;
11506       else
11507         value = Rn - imm32;
11508 
11509       context.type = eContextAdjustBaseRegister;
11510       context.SetRegisterPlusOffset(*base_reg, value - Rn);
11511 
11512       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11513                                  value))
11514         return false;
11515     }
11516 
11517     const uint32_t addr_byte_size = GetAddressByteSize();
11518     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11519 
11520     context.type = eContextRegisterStore;
11521     // for r = 0 to regs-1
11522     for (uint32_t r = 0; r < regs; ++r) {
11523 
11524       if (single_regs) {
11525         // MemA[address,4] = S[d+r]; address = address+4;
11526         uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11527                                              start_reg + d + r, 0, &success);
11528         if (!success)
11529           return false;
11530 
11531         std::optional<RegisterInfo> data_reg =
11532             GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r);
11533         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11534                                                 address - Rn);
11535         if (!MemAWrite(context, address, data, addr_byte_size))
11536           return false;
11537 
11538         address = address + 4;
11539       } else {
11540         // // Store as two word-aligned words in the correct order for current
11541         // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11542         // D[d+r]<31:0>;
11543         // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11544         // D[d+r]<63:32>;
11545         uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11546                                              start_reg + d + r, 0, &success);
11547         if (!success)
11548           return false;
11549 
11550         std::optional<RegisterInfo> data_reg =
11551             GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r);
11552 
11553         if (GetByteOrder() == eByteOrderBig) {
11554           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11555                                                   address - Rn);
11556           if (!MemAWrite(context, address, Bits64(data, 63, 32),
11557                          addr_byte_size))
11558             return false;
11559 
11560           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11561                                                   (address + 4) - Rn);
11562           if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11563                          addr_byte_size))
11564             return false;
11565         } else {
11566           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11567                                                   address - Rn);
11568           if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11569             return false;
11570 
11571           context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11572                                                   (address + 4) - Rn);
11573           if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11574                          addr_byte_size))
11575             return false;
11576         }
11577         // address = address+8;
11578         address = address + 8;
11579       }
11580     }
11581   }
11582   return true;
11583 }
11584 
11585 // A8.6.320
11586 // This instruction loads a single extension register from memory, using an
11587 // address from an ARM core register, with an optional offset.
EmulateVLDR(const uint32_t opcode,ARMEncoding encoding)11588 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11589                                         ARMEncoding encoding) {
11590 #if 0
11591     if ConditionPassed() then
11592         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11593         base = if n == 15 then Align(PC,4) else R[n];
11594         address = if add then (base + imm32) else (base - imm32);
11595         if single_reg then
11596             S[d] = MemA[address,4];
11597         else
11598             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11599             // Combine the word-aligned words in the correct order for current
11600             // endianness.
11601             D[d] = if BigEndian() then word1:word2 else word2:word1;
11602 #endif
11603 
11604   bool success = false;
11605 
11606   if (ConditionPassed(opcode)) {
11607     bool single_reg;
11608     bool add;
11609     uint32_t imm32;
11610     uint32_t d;
11611     uint32_t n;
11612 
11613     switch (encoding) {
11614     case eEncodingT1:
11615     case eEncodingA1:
11616       // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11617       // 32);
11618       single_reg = false;
11619       add = BitIsSet(opcode, 23);
11620       imm32 = Bits32(opcode, 7, 0) << 2;
11621 
11622       // d = UInt(D:Vd); n = UInt(Rn);
11623       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11624       n = Bits32(opcode, 19, 16);
11625 
11626       break;
11627 
11628     case eEncodingT2:
11629     case eEncodingA2:
11630       // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11631       single_reg = true;
11632       add = BitIsSet(opcode, 23);
11633       imm32 = Bits32(opcode, 7, 0) << 2;
11634 
11635       // d = UInt(Vd:D); n = UInt(Rn);
11636       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11637       n = Bits32(opcode, 19, 16);
11638 
11639       break;
11640 
11641     default:
11642       return false;
11643     }
11644     std::optional<RegisterInfo> base_reg =
11645         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11646 
11647     uint32_t Rn = ReadCoreReg(n, &success);
11648     if (!success)
11649       return false;
11650 
11651     // base = if n == 15 then Align(PC,4) else R[n];
11652     uint32_t base;
11653     if (n == 15)
11654       base = AlignPC(Rn);
11655     else
11656       base = Rn;
11657 
11658     // address = if add then (base + imm32) else (base - imm32);
11659     addr_t address;
11660     if (add)
11661       address = base + imm32;
11662     else
11663       address = base - imm32;
11664 
11665     const uint32_t addr_byte_size = GetAddressByteSize();
11666     uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11667 
11668     EmulateInstruction::Context context;
11669     context.type = eContextRegisterLoad;
11670     context.SetRegisterPlusOffset(*base_reg, address - base);
11671 
11672     if (single_reg) {
11673       // S[d] = MemA[address,4];
11674       uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11675       if (!success)
11676         return false;
11677 
11678       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11679                                  data))
11680         return false;
11681     } else {
11682       // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11683       uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11684       if (!success)
11685         return false;
11686 
11687       context.SetRegisterPlusOffset(*base_reg, (address + 4) - base);
11688       uint32_t word2 =
11689           MemARead(context, address + 4, addr_byte_size, 0, &success);
11690       if (!success)
11691         return false;
11692       // // Combine the word-aligned words in the correct order for current
11693       // endianness.
11694       // D[d] = if BigEndian() then word1:word2 else word2:word1;
11695       uint64_t data64;
11696       if (GetByteOrder() == eByteOrderBig) {
11697         data64 = word1;
11698         data64 = (data64 << 32) | word2;
11699       } else {
11700         data64 = word2;
11701         data64 = (data64 << 32) | word1;
11702       }
11703 
11704       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11705                                  data64))
11706         return false;
11707     }
11708   }
11709   return true;
11710 }
11711 
11712 // A8.6.400 VSTR
11713 // This instruction stores a signle extension register to memory, using an
11714 // address from an ARM core register, with an optional offset.
EmulateVSTR(const uint32_t opcode,ARMEncoding encoding)11715 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11716                                         ARMEncoding encoding) {
11717 #if 0
11718     if ConditionPassed() then
11719         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11720         address = if add then (R[n] + imm32) else (R[n] - imm32);
11721         if single_reg then
11722             MemA[address,4] = S[d];
11723         else
11724             // Store as two word-aligned words in the correct order for current
11725             // endianness.
11726             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11727             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11728 #endif
11729 
11730   bool success = false;
11731 
11732   if (ConditionPassed(opcode)) {
11733     bool single_reg;
11734     bool add;
11735     uint32_t imm32;
11736     uint32_t d;
11737     uint32_t n;
11738 
11739     switch (encoding) {
11740     case eEncodingT1:
11741     case eEncodingA1:
11742       // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11743       // 32);
11744       single_reg = false;
11745       add = BitIsSet(opcode, 23);
11746       imm32 = Bits32(opcode, 7, 0) << 2;
11747 
11748       // d = UInt(D:Vd); n = UInt(Rn);
11749       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11750       n = Bits32(opcode, 19, 16);
11751 
11752       // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11753       if ((n == 15) && (CurrentInstrSet() != eModeARM))
11754         return false;
11755 
11756       break;
11757 
11758     case eEncodingT2:
11759     case eEncodingA2:
11760       // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11761       single_reg = true;
11762       add = BitIsSet(opcode, 23);
11763       imm32 = Bits32(opcode, 7, 0) << 2;
11764 
11765       // d = UInt(Vd:D); n = UInt(Rn);
11766       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11767       n = Bits32(opcode, 19, 16);
11768 
11769       // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11770       if ((n == 15) && (CurrentInstrSet() != eModeARM))
11771         return false;
11772 
11773       break;
11774 
11775     default:
11776       return false;
11777     }
11778 
11779     uint32_t Rn = ReadCoreReg(n, &success);
11780     if (!success)
11781       return false;
11782 
11783     // address = if add then (R[n] + imm32) else (R[n] - imm32);
11784     addr_t address;
11785     if (add)
11786       address = Rn + imm32;
11787     else
11788       address = Rn - imm32;
11789 
11790     const uint32_t addr_byte_size = GetAddressByteSize();
11791     uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11792 
11793     std::optional<RegisterInfo> base_reg =
11794         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11795     std::optional<RegisterInfo> data_reg =
11796         GetRegisterInfo(eRegisterKindDWARF, start_reg + d);
11797     EmulateInstruction::Context context;
11798     context.type = eContextRegisterStore;
11799     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
11800 
11801     if (single_reg) {
11802       // MemA[address,4] = S[d];
11803       uint32_t data =
11804           ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11805       if (!success)
11806         return false;
11807 
11808       if (!MemAWrite(context, address, data, addr_byte_size))
11809         return false;
11810     } else {
11811       // // Store as two word-aligned words in the correct order for current
11812       // endianness.
11813       // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11814       // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11815       uint64_t data =
11816           ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11817       if (!success)
11818         return false;
11819 
11820       if (GetByteOrder() == eByteOrderBig) {
11821         if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11822           return false;
11823 
11824         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11825                                                 (address + 4) - Rn);
11826         if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11827                        addr_byte_size))
11828           return false;
11829       } else {
11830         if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11831           return false;
11832 
11833         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
11834                                                 (address + 4) - Rn);
11835         if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11836                        addr_byte_size))
11837           return false;
11838       }
11839     }
11840   }
11841   return true;
11842 }
11843 
11844 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11845 // from memory into one, two, three or four registers, without de-interleaving.
11846 // Every element of each register is loaded.
EmulateVLD1Multiple(const uint32_t opcode,ARMEncoding encoding)11847 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11848                                                 ARMEncoding encoding) {
11849 #if 0
11850     if ConditionPassed() then
11851         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11852         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11853         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11854         for r = 0 to regs-1
11855             for e = 0 to elements-1
11856                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11857                 address = address + ebytes;
11858 #endif
11859 
11860   bool success = false;
11861 
11862   if (ConditionPassed(opcode)) {
11863     uint32_t regs;
11864     uint32_t alignment;
11865     uint32_t ebytes;
11866     uint32_t esize;
11867     uint32_t elements;
11868     uint32_t d;
11869     uint32_t n;
11870     uint32_t m;
11871     bool wback;
11872     bool register_index;
11873 
11874     switch (encoding) {
11875     case eEncodingT1:
11876     case eEncodingA1: {
11877       // case type of
11878       // when '0111'
11879       // regs = 1; if align<1> == '1' then UNDEFINED;
11880       // when '1010'
11881       // regs = 2; if align == '11' then UNDEFINED;
11882       // when '0110'
11883       // regs = 3; if align<1> == '1' then UNDEFINED;
11884       // when '0010'
11885       // regs = 4;
11886       // otherwise
11887       // SEE 'Related encodings';
11888       uint32_t type = Bits32(opcode, 11, 8);
11889       uint32_t align = Bits32(opcode, 5, 4);
11890       if (type == 7) // '0111'
11891       {
11892         regs = 1;
11893         if (BitIsSet(align, 1))
11894           return false;
11895       } else if (type == 10) // '1010'
11896       {
11897         regs = 2;
11898         if (align == 3)
11899           return false;
11900 
11901       } else if (type == 6) // '0110'
11902       {
11903         regs = 3;
11904         if (BitIsSet(align, 1))
11905           return false;
11906       } else if (type == 2) // '0010'
11907       {
11908         regs = 4;
11909       } else
11910         return false;
11911 
11912       // alignment = if align == '00' then 1 else 4 << UInt(align);
11913       if (align == 0)
11914         alignment = 1;
11915       else
11916         alignment = 4 << align;
11917 
11918       // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11919       ebytes = 1 << Bits32(opcode, 7, 6);
11920       esize = 8 * ebytes;
11921       elements = 8 / ebytes;
11922 
11923       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11924       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11925       n = Bits32(opcode, 19, 15);
11926       m = Bits32(opcode, 3, 0);
11927 
11928       // wback = (m != 15); register_index = (m != 15 && m != 13);
11929       wback = (m != 15);
11930       register_index = ((m != 15) && (m != 13));
11931 
11932       // if d+regs > 32 then UNPREDICTABLE;
11933       if ((d + regs) > 32)
11934         return false;
11935     } break;
11936 
11937     default:
11938       return false;
11939     }
11940 
11941     std::optional<RegisterInfo> base_reg =
11942         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
11943 
11944     uint32_t Rn = ReadCoreReg(n, &success);
11945     if (!success)
11946       return false;
11947 
11948     // address = R[n]; if (address MOD alignment) != 0 then
11949     // GenerateAlignmentException();
11950     addr_t address = Rn;
11951     if ((address % alignment) != 0)
11952       return false;
11953 
11954     EmulateInstruction::Context context;
11955     // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11956     if (wback) {
11957       uint32_t Rm = ReadCoreReg(m, &success);
11958       if (!success)
11959         return false;
11960 
11961       uint32_t offset;
11962       if (register_index)
11963         offset = Rm;
11964       else
11965         offset = 8 * regs;
11966 
11967       uint32_t value = Rn + offset;
11968       context.type = eContextAdjustBaseRegister;
11969       context.SetRegisterPlusOffset(*base_reg, offset);
11970 
11971       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11972                                  value))
11973         return false;
11974     }
11975 
11976     // for r = 0 to regs-1
11977     for (uint32_t r = 0; r < regs; ++r) {
11978       // for e = 0 to elements-1
11979       uint64_t assembled_data = 0;
11980       for (uint32_t e = 0; e < elements; ++e) {
11981         // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11982         context.type = eContextRegisterLoad;
11983         context.SetRegisterPlusOffset(*base_reg, address - Rn);
11984         uint64_t data = MemURead(context, address, ebytes, 0, &success);
11985         if (!success)
11986           return false;
11987 
11988         assembled_data =
11989             (data << (e * esize)) |
11990             assembled_data; // New data goes to the left of existing data
11991 
11992         // address = address + ebytes;
11993         address = address + ebytes;
11994       }
11995       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
11996                                  assembled_data))
11997         return false;
11998     }
11999   }
12000   return true;
12001 }
12002 
12003 // A8.6.308 VLD1 (single element to one lane)
12004 //
EmulateVLD1Single(const uint32_t opcode,const ARMEncoding encoding)12005 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12006                                               const ARMEncoding encoding) {
12007 #if 0
12008     if ConditionPassed() then
12009         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12010         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12011         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12012         Elem[D[d],index,esize] = MemU[address,ebytes];
12013 #endif
12014 
12015   bool success = false;
12016 
12017   if (ConditionPassed(opcode)) {
12018     uint32_t ebytes;
12019     uint32_t esize;
12020     uint32_t index;
12021     uint32_t alignment;
12022     uint32_t d;
12023     uint32_t n;
12024     uint32_t m;
12025     bool wback;
12026     bool register_index;
12027 
12028     switch (encoding) {
12029     case eEncodingT1:
12030     case eEncodingA1: {
12031       uint32_t size = Bits32(opcode, 11, 10);
12032       uint32_t index_align = Bits32(opcode, 7, 4);
12033       // if size == '11' then SEE VLD1 (single element to all lanes);
12034       if (size == 3)
12035         return EmulateVLD1SingleAll(opcode, encoding);
12036       // case size of
12037       if (size == 0) // when '00'
12038       {
12039         // if index_align<0> != '0' then UNDEFINED;
12040         if (BitIsClear(index_align, 0))
12041           return false;
12042 
12043         // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12044         ebytes = 1;
12045         esize = 8;
12046         index = Bits32(index_align, 3, 1);
12047         alignment = 1;
12048       } else if (size == 1) // when '01'
12049       {
12050         // if index_align<1> != '0' then UNDEFINED;
12051         if (BitIsClear(index_align, 1))
12052           return false;
12053 
12054         // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12055         ebytes = 2;
12056         esize = 16;
12057         index = Bits32(index_align, 3, 2);
12058 
12059         // alignment = if index_align<0> == '0' then 1 else 2;
12060         if (BitIsClear(index_align, 0))
12061           alignment = 1;
12062         else
12063           alignment = 2;
12064       } else if (size == 2) // when '10'
12065       {
12066         // if index_align<2> != '0' then UNDEFINED;
12067         if (BitIsClear(index_align, 2))
12068           return false;
12069 
12070         // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12071         // UNDEFINED;
12072         if ((Bits32(index_align, 1, 0) != 0) &&
12073             (Bits32(index_align, 1, 0) != 3))
12074           return false;
12075 
12076         // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12077         ebytes = 4;
12078         esize = 32;
12079         index = Bit32(index_align, 3);
12080 
12081         // alignment = if index_align<1:0> == '00' then 1 else 4;
12082         if (Bits32(index_align, 1, 0) == 0)
12083           alignment = 1;
12084         else
12085           alignment = 4;
12086       } else {
12087         return false;
12088       }
12089       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12090       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12091       n = Bits32(opcode, 19, 16);
12092       m = Bits32(opcode, 3, 0);
12093 
12094       // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12095       // then UNPREDICTABLE;
12096       wback = (m != 15);
12097       register_index = ((m != 15) && (m != 13));
12098 
12099       if (n == 15)
12100         return false;
12101 
12102     } break;
12103 
12104     default:
12105       return false;
12106     }
12107 
12108     uint32_t Rn = ReadCoreReg(n, &success);
12109     if (!success)
12110       return false;
12111 
12112     // address = R[n]; if (address MOD alignment) != 0 then
12113     // GenerateAlignmentException();
12114     addr_t address = Rn;
12115     if ((address % alignment) != 0)
12116       return false;
12117 
12118     EmulateInstruction::Context context;
12119     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12120     if (wback) {
12121       uint32_t Rm = ReadCoreReg(m, &success);
12122       if (!success)
12123         return false;
12124 
12125       uint32_t offset;
12126       if (register_index)
12127         offset = Rm;
12128       else
12129         offset = ebytes;
12130 
12131       uint32_t value = Rn + offset;
12132 
12133       context.type = eContextAdjustBaseRegister;
12134       std::optional<RegisterInfo> base_reg =
12135           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12136       context.SetRegisterPlusOffset(*base_reg, offset);
12137 
12138       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12139                                  value))
12140         return false;
12141     }
12142 
12143     // Elem[D[d],index,esize] = MemU[address,ebytes];
12144     uint32_t element = MemURead(context, address, esize, 0, &success);
12145     if (!success)
12146       return false;
12147 
12148     element = element << (index * esize);
12149 
12150     uint64_t reg_data =
12151         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12152     if (!success)
12153       return false;
12154 
12155     uint64_t all_ones = -1;
12156     uint64_t mask = all_ones
12157                     << ((index + 1) * esize); // mask is all 1's to left of
12158                                               // where 'element' goes, & all 0's
12159     // at element & to the right of element.
12160     if (index > 0)
12161       mask = mask | Bits64(all_ones, (index * esize) - 1,
12162                            0); // add 1's to the right of where 'element' goes.
12163     // now mask should be 0's where element goes & 1's everywhere else.
12164 
12165     uint64_t masked_reg =
12166         reg_data & mask; // Take original reg value & zero out 'element' bits
12167     reg_data =
12168         masked_reg & element; // Put 'element' into those bits in reg_data.
12169 
12170     context.type = eContextRegisterLoad;
12171     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12172                                reg_data))
12173       return false;
12174   }
12175   return true;
12176 }
12177 
12178 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12179 // elements) stores elements to memory from one, two, three, or four registers,
12180 // without interleaving.  Every element of each register is stored.
EmulateVST1Multiple(const uint32_t opcode,ARMEncoding encoding)12181 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12182                                                 ARMEncoding encoding) {
12183 #if 0
12184     if ConditionPassed() then
12185         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12186         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12187         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12188         for r = 0 to regs-1
12189             for e = 0 to elements-1
12190                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12191                 address = address + ebytes;
12192 #endif
12193 
12194   bool success = false;
12195 
12196   if (ConditionPassed(opcode)) {
12197     uint32_t regs;
12198     uint32_t alignment;
12199     uint32_t ebytes;
12200     uint32_t esize;
12201     uint32_t elements;
12202     uint32_t d;
12203     uint32_t n;
12204     uint32_t m;
12205     bool wback;
12206     bool register_index;
12207 
12208     switch (encoding) {
12209     case eEncodingT1:
12210     case eEncodingA1: {
12211       uint32_t type = Bits32(opcode, 11, 8);
12212       uint32_t align = Bits32(opcode, 5, 4);
12213 
12214       // case type of
12215       if (type == 7) // when '0111'
12216       {
12217         // regs = 1; if align<1> == '1' then UNDEFINED;
12218         regs = 1;
12219         if (BitIsSet(align, 1))
12220           return false;
12221       } else if (type == 10) // when '1010'
12222       {
12223         // regs = 2; if align == '11' then UNDEFINED;
12224         regs = 2;
12225         if (align == 3)
12226           return false;
12227       } else if (type == 6) // when '0110'
12228       {
12229         // regs = 3; if align<1> == '1' then UNDEFINED;
12230         regs = 3;
12231         if (BitIsSet(align, 1))
12232           return false;
12233       } else if (type == 2) // when '0010'
12234         // regs = 4;
12235         regs = 4;
12236       else // otherwise
12237         // SEE 'Related encodings';
12238         return false;
12239 
12240       // alignment = if align == '00' then 1 else 4 << UInt(align);
12241       if (align == 0)
12242         alignment = 1;
12243       else
12244         alignment = 4 << align;
12245 
12246       // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12247       ebytes = 1 << Bits32(opcode, 7, 6);
12248       esize = 8 * ebytes;
12249       elements = 8 / ebytes;
12250 
12251       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12252       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12253       n = Bits32(opcode, 19, 16);
12254       m = Bits32(opcode, 3, 0);
12255 
12256       // wback = (m != 15); register_index = (m != 15 && m != 13);
12257       wback = (m != 15);
12258       register_index = ((m != 15) && (m != 13));
12259 
12260       // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12261       if ((d + regs) > 32)
12262         return false;
12263 
12264       if (n == 15)
12265         return false;
12266 
12267     } break;
12268 
12269     default:
12270       return false;
12271     }
12272 
12273     std::optional<RegisterInfo> base_reg =
12274         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12275 
12276     uint32_t Rn = ReadCoreReg(n, &success);
12277     if (!success)
12278       return false;
12279 
12280     // address = R[n]; if (address MOD alignment) != 0 then
12281     // GenerateAlignmentException();
12282     addr_t address = Rn;
12283     if ((address % alignment) != 0)
12284       return false;
12285 
12286     EmulateInstruction::Context context;
12287     // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12288     if (wback) {
12289       uint32_t Rm = ReadCoreReg(m, &success);
12290       if (!success)
12291         return false;
12292 
12293       uint32_t offset;
12294       if (register_index)
12295         offset = Rm;
12296       else
12297         offset = 8 * regs;
12298 
12299       context.type = eContextAdjustBaseRegister;
12300       context.SetRegisterPlusOffset(*base_reg, offset);
12301 
12302       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12303                                  Rn + offset))
12304         return false;
12305     }
12306 
12307     context.type = eContextRegisterStore;
12308     // for r = 0 to regs-1
12309     for (uint32_t r = 0; r < regs; ++r) {
12310       std::optional<RegisterInfo> data_reg =
12311           GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r);
12312       uint64_t register_data = ReadRegisterUnsigned(
12313           eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12314       if (!success)
12315         return false;
12316 
12317       // for e = 0 to elements-1
12318       for (uint32_t e = 0; e < elements; ++e) {
12319         // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12320         uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12321 
12322         context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg,
12323                                                 address - Rn);
12324         if (!MemUWrite(context, address, word, ebytes))
12325           return false;
12326 
12327         // address = address + ebytes;
12328         address = address + ebytes;
12329       }
12330     }
12331   }
12332   return true;
12333 }
12334 
12335 // A8.6.392 VST1 (single element from one lane) This instruction stores one
12336 // element to memory from one element of a register.
EmulateVST1Single(const uint32_t opcode,ARMEncoding encoding)12337 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12338                                               ARMEncoding encoding) {
12339 #if 0
12340     if ConditionPassed() then
12341         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12342         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12343         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12344         MemU[address,ebytes] = Elem[D[d],index,esize];
12345 #endif
12346 
12347   bool success = false;
12348 
12349   if (ConditionPassed(opcode)) {
12350     uint32_t ebytes;
12351     uint32_t esize;
12352     uint32_t index;
12353     uint32_t alignment;
12354     uint32_t d;
12355     uint32_t n;
12356     uint32_t m;
12357     bool wback;
12358     bool register_index;
12359 
12360     switch (encoding) {
12361     case eEncodingT1:
12362     case eEncodingA1: {
12363       uint32_t size = Bits32(opcode, 11, 10);
12364       uint32_t index_align = Bits32(opcode, 7, 4);
12365 
12366       // if size == '11' then UNDEFINED;
12367       if (size == 3)
12368         return false;
12369 
12370       // case size of
12371       if (size == 0) // when '00'
12372       {
12373         // if index_align<0> != '0' then UNDEFINED;
12374         if (BitIsClear(index_align, 0))
12375           return false;
12376         // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12377         ebytes = 1;
12378         esize = 8;
12379         index = Bits32(index_align, 3, 1);
12380         alignment = 1;
12381       } else if (size == 1) // when '01'
12382       {
12383         // if index_align<1> != '0' then UNDEFINED;
12384         if (BitIsClear(index_align, 1))
12385           return false;
12386 
12387         // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12388         ebytes = 2;
12389         esize = 16;
12390         index = Bits32(index_align, 3, 2);
12391 
12392         // alignment = if index_align<0> == '0' then 1 else 2;
12393         if (BitIsClear(index_align, 0))
12394           alignment = 1;
12395         else
12396           alignment = 2;
12397       } else if (size == 2) // when '10'
12398       {
12399         // if index_align<2> != '0' then UNDEFINED;
12400         if (BitIsClear(index_align, 2))
12401           return false;
12402 
12403         // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12404         // UNDEFINED;
12405         if ((Bits32(index_align, 1, 0) != 0) &&
12406             (Bits32(index_align, 1, 0) != 3))
12407           return false;
12408 
12409         // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12410         ebytes = 4;
12411         esize = 32;
12412         index = Bit32(index_align, 3);
12413 
12414         // alignment = if index_align<1:0> == '00' then 1 else 4;
12415         if (Bits32(index_align, 1, 0) == 0)
12416           alignment = 1;
12417         else
12418           alignment = 4;
12419       } else {
12420         return false;
12421       }
12422       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12423       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12424       n = Bits32(opcode, 19, 16);
12425       m = Bits32(opcode, 3, 0);
12426 
12427       // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12428       // then UNPREDICTABLE;
12429       wback = (m != 15);
12430       register_index = ((m != 15) && (m != 13));
12431 
12432       if (n == 15)
12433         return false;
12434     } break;
12435 
12436     default:
12437       return false;
12438     }
12439 
12440     std::optional<RegisterInfo> base_reg =
12441         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12442 
12443     uint32_t Rn = ReadCoreReg(n, &success);
12444     if (!success)
12445       return false;
12446 
12447     // address = R[n]; if (address MOD alignment) != 0 then
12448     // GenerateAlignmentException();
12449     addr_t address = Rn;
12450     if ((address % alignment) != 0)
12451       return false;
12452 
12453     EmulateInstruction::Context context;
12454     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12455     if (wback) {
12456       uint32_t Rm = ReadCoreReg(m, &success);
12457       if (!success)
12458         return false;
12459 
12460       uint32_t offset;
12461       if (register_index)
12462         offset = Rm;
12463       else
12464         offset = ebytes;
12465 
12466       context.type = eContextAdjustBaseRegister;
12467       context.SetRegisterPlusOffset(*base_reg, offset);
12468 
12469       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12470                                  Rn + offset))
12471         return false;
12472     }
12473 
12474     // MemU[address,ebytes] = Elem[D[d],index,esize];
12475     uint64_t register_data =
12476         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12477     if (!success)
12478       return false;
12479 
12480     uint64_t word =
12481         Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12482 
12483     std::optional<RegisterInfo> data_reg =
12484         GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d);
12485     context.type = eContextRegisterStore;
12486     context.SetRegisterToRegisterPlusOffset(*data_reg, *base_reg, address - Rn);
12487 
12488     if (!MemUWrite(context, address, word, ebytes))
12489       return false;
12490   }
12491   return true;
12492 }
12493 
12494 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12495 // element from memory into every element of one or two vectors.
EmulateVLD1SingleAll(const uint32_t opcode,const ARMEncoding encoding)12496 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12497                                                  const ARMEncoding encoding) {
12498 #if 0
12499     if ConditionPassed() then
12500         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12501         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12502         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12503         replicated_element = Replicate(MemU[address,ebytes], elements);
12504         for r = 0 to regs-1
12505             D[d+r] = replicated_element;
12506 #endif
12507 
12508   bool success = false;
12509 
12510   if (ConditionPassed(opcode)) {
12511     uint32_t ebytes;
12512     uint32_t elements;
12513     uint32_t regs;
12514     uint32_t alignment;
12515     uint32_t d;
12516     uint32_t n;
12517     uint32_t m;
12518     bool wback;
12519     bool register_index;
12520 
12521     switch (encoding) {
12522     case eEncodingT1:
12523     case eEncodingA1: {
12524       // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12525       uint32_t size = Bits32(opcode, 7, 6);
12526       if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12527         return false;
12528 
12529       // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12530       // then 1 else 2;
12531       ebytes = 1 << size;
12532       elements = 8 / ebytes;
12533       if (BitIsClear(opcode, 5))
12534         regs = 1;
12535       else
12536         regs = 2;
12537 
12538       // alignment = if a == '0' then 1 else ebytes;
12539       if (BitIsClear(opcode, 4))
12540         alignment = 1;
12541       else
12542         alignment = ebytes;
12543 
12544       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12545       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12546       n = Bits32(opcode, 19, 16);
12547       m = Bits32(opcode, 3, 0);
12548 
12549       // wback = (m != 15); register_index = (m != 15 && m != 13);
12550       wback = (m != 15);
12551       register_index = ((m != 15) && (m != 13));
12552 
12553       // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12554       if ((d + regs) > 32)
12555         return false;
12556 
12557       if (n == 15)
12558         return false;
12559     } break;
12560 
12561     default:
12562       return false;
12563     }
12564 
12565     uint32_t Rn = ReadCoreReg(n, &success);
12566     if (!success)
12567       return false;
12568 
12569     // address = R[n]; if (address MOD alignment) != 0 then
12570     // GenerateAlignmentException();
12571     addr_t address = Rn;
12572     if ((address % alignment) != 0)
12573       return false;
12574 
12575     EmulateInstruction::Context context;
12576     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12577     if (wback) {
12578       uint32_t Rm = ReadCoreReg(m, &success);
12579       if (!success)
12580         return false;
12581 
12582       uint32_t offset;
12583       if (register_index)
12584         offset = Rm;
12585       else
12586         offset = ebytes;
12587 
12588       context.type = eContextAdjustBaseRegister;
12589       std::optional<RegisterInfo> base_reg =
12590           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n);
12591       context.SetRegisterPlusOffset(*base_reg, offset);
12592 
12593       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12594                                  Rn + offset))
12595         return false;
12596     }
12597 
12598     // replicated_element = Replicate(MemU[address,ebytes], elements);
12599 
12600     context.type = eContextRegisterLoad;
12601     uint64_t word = MemURead(context, address, ebytes, 0, &success);
12602     if (!success)
12603       return false;
12604 
12605     uint64_t replicated_element = 0;
12606     uint32_t esize = ebytes * 8;
12607     for (uint32_t e = 0; e < elements; ++e)
12608       replicated_element =
12609           (replicated_element << esize) | Bits64(word, esize - 1, 0);
12610 
12611     // for r = 0 to regs-1
12612     for (uint32_t r = 0; r < regs; ++r) {
12613       // D[d+r] = replicated_element;
12614       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12615                                  replicated_element))
12616         return false;
12617     }
12618   }
12619   return true;
12620 }
12621 
12622 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12623 // instruction provides an exception return without the use of the stack.  It
12624 // subtracts the immediate constant from the LR, branches to the resulting
12625 // address, and also copies the SPSR to the CPSR.
EmulateSUBSPcLrEtc(const uint32_t opcode,const ARMEncoding encoding)12626 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12627                                                const ARMEncoding encoding) {
12628 #if 0
12629     if ConditionPassed() then
12630         EncodingSpecificOperations();
12631         if CurrentInstrSet() == InstrSet_ThumbEE then
12632             UNPREDICTABLE;
12633         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12634         case opcode of
12635             when '0000' result = R[n] AND operand2; // AND
12636             when '0001' result = R[n] EOR operand2; // EOR
12637             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12638             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12639             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12640             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12641             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12642             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12643             when '1100' result = R[n] OR operand2; // ORR
12644             when '1101' result = operand2; // MOV
12645             when '1110' result = R[n] AND NOT(operand2); // BIC
12646             when '1111' result = NOT(operand2); // MVN
12647         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12648         BranchWritePC(result);
12649 #endif
12650 
12651   bool success = false;
12652 
12653   if (ConditionPassed(opcode)) {
12654     uint32_t n;
12655     uint32_t m;
12656     uint32_t imm32;
12657     bool register_form;
12658     ARM_ShifterType shift_t;
12659     uint32_t shift_n;
12660     uint32_t code;
12661 
12662     switch (encoding) {
12663     case eEncodingT1:
12664       // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12665       // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12666       // // = SUB
12667       n = 14;
12668       imm32 = Bits32(opcode, 7, 0);
12669       register_form = false;
12670       code = 2;
12671 
12672       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12673       if (InITBlock() && !LastInITBlock())
12674         return false;
12675 
12676       break;
12677 
12678     case eEncodingA1:
12679       // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12680       n = Bits32(opcode, 19, 16);
12681       imm32 = ARMExpandImm(opcode);
12682       register_form = false;
12683       code = Bits32(opcode, 24, 21);
12684 
12685       break;
12686 
12687     case eEncodingA2:
12688       // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12689       n = Bits32(opcode, 19, 16);
12690       m = Bits32(opcode, 3, 0);
12691       register_form = true;
12692 
12693       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12694       shift_n = DecodeImmShiftARM(opcode, shift_t);
12695 
12696       break;
12697 
12698     default:
12699       return false;
12700     }
12701 
12702     // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12703     // else imm32;
12704     uint32_t operand2;
12705     if (register_form) {
12706       uint32_t Rm = ReadCoreReg(m, &success);
12707       if (!success)
12708         return false;
12709 
12710       operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12711       if (!success)
12712         return false;
12713     } else {
12714       operand2 = imm32;
12715     }
12716 
12717     uint32_t Rn = ReadCoreReg(n, &success);
12718     if (!success)
12719       return false;
12720 
12721     AddWithCarryResult result;
12722 
12723     // case opcode of
12724     switch (code) {
12725     case 0: // when '0000'
12726       // result = R[n] AND operand2; // AND
12727       result.result = Rn & operand2;
12728       break;
12729 
12730     case 1: // when '0001'
12731       // result = R[n] EOR operand2; // EOR
12732       result.result = Rn ^ operand2;
12733       break;
12734 
12735     case 2: // when '0010'
12736       // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12737       result = AddWithCarry(Rn, ~(operand2), 1);
12738       break;
12739 
12740     case 3: // when '0011'
12741       // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12742       result = AddWithCarry(~(Rn), operand2, 1);
12743       break;
12744 
12745     case 4: // when '0100'
12746       // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12747       result = AddWithCarry(Rn, operand2, 0);
12748       break;
12749 
12750     case 5: // when '0101'
12751       // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12752       result = AddWithCarry(Rn, operand2, APSR_C);
12753       break;
12754 
12755     case 6: // when '0110'
12756       // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12757       result = AddWithCarry(Rn, ~(operand2), APSR_C);
12758       break;
12759 
12760     case 7: // when '0111'
12761       // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12762       result = AddWithCarry(~(Rn), operand2, APSR_C);
12763       break;
12764 
12765     case 10: // when '1100'
12766       // result = R[n] OR operand2; // ORR
12767       result.result = Rn | operand2;
12768       break;
12769 
12770     case 11: // when '1101'
12771       // result = operand2; // MOV
12772       result.result = operand2;
12773       break;
12774 
12775     case 12: // when '1110'
12776       // result = R[n] AND NOT(operand2); // BIC
12777       result.result = Rn & ~(operand2);
12778       break;
12779 
12780     case 15: // when '1111'
12781       // result = NOT(operand2); // MVN
12782       result.result = ~(operand2);
12783       break;
12784 
12785     default:
12786       return false;
12787     }
12788     // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12789 
12790     // For now, in emulation mode, we don't have access to the SPSR, so we will
12791     // use the CPSR instead, and hope for the best.
12792     uint32_t spsr =
12793         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12794     if (!success)
12795       return false;
12796 
12797     CPSRWriteByInstr(spsr, 15, true);
12798 
12799     // BranchWritePC(result);
12800     EmulateInstruction::Context context;
12801     context.type = eContextAdjustPC;
12802     context.SetImmediate(result.result);
12803 
12804     BranchWritePC(context, result.result);
12805   }
12806   return true;
12807 }
12808 
12809 EmulateInstructionARM::ARMOpcode *
GetARMOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)12810 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12811                                                   uint32_t arm_isa) {
12812   static ARMOpcode g_arm_opcodes[] = {
12813       // Prologue instructions
12814 
12815       // push register(s)
12816       {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12817        &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12818       {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12819        &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12820 
12821       // set r7 to point to a stack offset
12822       {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12823        &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12824       {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12825        &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12826       // copy the stack pointer to ip
12827       {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12828        &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12829       {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12830        &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12831       {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12832        &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12833 
12834       // adjust the stack pointer
12835       {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12836        &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12837       {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12838        &EmulateInstructionARM::EmulateSUBSPReg,
12839        "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12840 
12841       // push one register
12842       // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12843       {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12844        &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12845 
12846       // vector push consecutive extension register(s)
12847       {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12848        &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12849       {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12850        &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12851 
12852       // Epilogue instructions
12853 
12854       {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12855        &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12856       {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12857        &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12858       {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12859        &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12860       {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12861        &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12862 
12863       // Supervisor Call (previously Software Interrupt)
12864       {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12865        &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12866 
12867       // Branch instructions
12868       // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12869       // "bl <label>".
12870       {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12871        &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12872       {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12873        &EmulateInstructionARM::EmulateB, "b #imm24"},
12874       {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12875        &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12876       {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12877        &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12878       // for example, "bx lr"
12879       {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12880        &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12881       // bxj
12882       {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12883        &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12884 
12885       // Data-processing instructions
12886       // adc (immediate)
12887       {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12888        &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12889       // adc (register)
12890       {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12891        &EmulateInstructionARM::EmulateADCReg,
12892        "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12893       // add (immediate)
12894       {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12895        &EmulateInstructionARM::EmulateADDImmARM,
12896        "add{s}<c> <Rd>, <Rn>, #const"},
12897       // add (register)
12898       {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12899        &EmulateInstructionARM::EmulateADDReg,
12900        "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12901       // add (register-shifted register)
12902       {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12903        &EmulateInstructionARM::EmulateADDRegShift,
12904        "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12905       // adr
12906       {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12907        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12908       {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12909        &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12910       // and (immediate)
12911       {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12912        &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12913       // and (register)
12914       {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12915        &EmulateInstructionARM::EmulateANDReg,
12916        "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12917       // bic (immediate)
12918       {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12919        &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12920       // bic (register)
12921       {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12922        &EmulateInstructionARM::EmulateBICReg,
12923        "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12924       // eor (immediate)
12925       {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926        &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12927       // eor (register)
12928       {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12929        &EmulateInstructionARM::EmulateEORReg,
12930        "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12931       // orr (immediate)
12932       {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12933        &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12934       // orr (register)
12935       {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12936        &EmulateInstructionARM::EmulateORRReg,
12937        "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12938       // rsb (immediate)
12939       {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12940        &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12941       // rsb (register)
12942       {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12943        &EmulateInstructionARM::EmulateRSBReg,
12944        "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12945       // rsc (immediate)
12946       {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12947        &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12948       // rsc (register)
12949       {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12950        &EmulateInstructionARM::EmulateRSCReg,
12951        "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12952       // sbc (immediate)
12953       {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12954        &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12955       // sbc (register)
12956       {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12957        &EmulateInstructionARM::EmulateSBCReg,
12958        "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12959       // sub (immediate, ARM)
12960       {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12961        &EmulateInstructionARM::EmulateSUBImmARM,
12962        "sub{s}<c> <Rd>, <Rn>, #<const>"},
12963       // sub (sp minus immediate)
12964       {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12965        &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12966       // sub (register)
12967       {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968        &EmulateInstructionARM::EmulateSUBReg,
12969        "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12970       // teq (immediate)
12971       {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12972        &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12973       // teq (register)
12974       {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975        &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12976       // tst (immediate)
12977       {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12978        &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12979       // tst (register)
12980       {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12981        &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12982 
12983       // mov (immediate)
12984       {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12985        &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12986       {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12987        &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
12988       // mov (register)
12989       {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12990        &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12991       // mvn (immediate)
12992       {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12993        &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12994       // mvn (register)
12995       {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996        &EmulateInstructionARM::EmulateMVNReg,
12997        "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12998       // cmn (immediate)
12999       {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13000        &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13001       // cmn (register)
13002       {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13004       // cmp (immediate)
13005       {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13006        &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13007       // cmp (register)
13008       {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13009        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13010       // asr (immediate)
13011       {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13012        &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13013       // asr (register)
13014       {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13015        &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13016       // lsl (immediate)
13017       {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13018        &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13019       // lsl (register)
13020       {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13021        &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13022       // lsr (immediate)
13023       {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13024        &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13025       // lsr (register)
13026       {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13027        &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13028       // rrx is a special case encoding of ror (immediate)
13029       {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13030        &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13031       // ror (immediate)
13032       {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13033        &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13034       // ror (register)
13035       {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13036        &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13037       // mul
13038       {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13039        &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13040 
13041       // subs pc, lr and related instructions
13042       {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13043        &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13044        "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13045       {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13046        &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13047        "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13048 
13049       // Load instructions
13050       {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13051        &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13052       {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053        &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13054       {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13055        &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13056       {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13057        &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13058       {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059        &EmulateInstructionARM::EmulateLDRImmediateARM,
13060        "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13061       {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062        &EmulateInstructionARM::EmulateLDRRegister,
13063        "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13064       {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065        &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13066       {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13067        &EmulateInstructionARM::EmulateLDRBRegister,
13068        "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13069       {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13070        &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13071       {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13072        &EmulateInstructionARM::EmulateLDRHRegister,
13073        "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13074       {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13075        &EmulateInstructionARM::EmulateLDRSBImmediate,
13076        "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13077       {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13078        &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13079       {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13080        &EmulateInstructionARM::EmulateLDRSBRegister,
13081        "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13082       {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13083        &EmulateInstructionARM::EmulateLDRSHImmediate,
13084        "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13085       {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13086        &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13087       {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13088        &EmulateInstructionARM::EmulateLDRSHRegister,
13089        "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13090       {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13091        &EmulateInstructionARM::EmulateLDRDImmediate,
13092        "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13093       {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13094        &EmulateInstructionARM::EmulateLDRDRegister,
13095        "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13096       {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13097        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13098       {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13099        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13100       {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13101        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13102       {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13103        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13104       {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13105        &EmulateInstructionARM::EmulateVLD1Multiple,
13106        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13107       {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13108        &EmulateInstructionARM::EmulateVLD1Single,
13109        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13110       {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13111        &EmulateInstructionARM::EmulateVLD1SingleAll,
13112        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13113 
13114       // Store instructions
13115       {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13116        &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13117       {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13118        &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13119       {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13120        &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13121       {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13122        &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13123       {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13124        &EmulateInstructionARM::EmulateSTRRegister,
13125        "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13126       {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13127        &EmulateInstructionARM::EmulateSTRHRegister,
13128        "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13129       {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13130        &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13131       {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13132        &EmulateInstructionARM::EmulateSTRBImmARM,
13133        "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13134       {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13135        &EmulateInstructionARM::EmulateSTRImmARM,
13136        "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13137       {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13138        &EmulateInstructionARM::EmulateSTRDImm,
13139        "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13140       {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13141        &EmulateInstructionARM::EmulateSTRDReg,
13142        "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13143       {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13144        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13145       {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13146        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13147       {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13148        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13149       {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13150        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13151       {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13152        &EmulateInstructionARM::EmulateVST1Multiple,
13153        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13154       {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13155        &EmulateInstructionARM::EmulateVST1Single,
13156        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13157 
13158       // Other instructions
13159       {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13160        &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13161       {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13162        &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13163       {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13164        &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13165       {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13166        &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13167       {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13168        &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13169 
13170   };
13171   static const size_t k_num_arm_opcodes = std::size(g_arm_opcodes);
13172 
13173   for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13174     if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13175         (g_arm_opcodes[i].variants & arm_isa) != 0)
13176       return &g_arm_opcodes[i];
13177   }
13178   return nullptr;
13179 }
13180 
13181 EmulateInstructionARM::ARMOpcode *
GetThumbOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)13182 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13183                                                     uint32_t arm_isa) {
13184 
13185   static ARMOpcode g_thumb_opcodes[] = {
13186       // Prologue instructions
13187 
13188       // push register(s)
13189       {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13190        &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13191       {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13192        &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13193       {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13194        &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13195 
13196       // set r7 to point to a stack offset
13197       {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13198        &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13199       // copy the stack pointer to r7
13200       {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13201        &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13202       // move from high register to low register (comes after "mov r7, sp" to
13203       // resolve ambiguity)
13204       {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13205        &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13206 
13207       // PC-relative load into register (see also EmulateADDSPRm)
13208       {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13209        &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13210 
13211       // adjust the stack pointer
13212       {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13213        &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13214       {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13215        &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13216       {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13217        &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13218       {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13219        &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13220       {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13221        &EmulateInstructionARM::EmulateSUBSPReg,
13222        "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13223 
13224       // vector push consecutive extension register(s)
13225       {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13226        &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13227       {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13228        &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13229 
13230       // Epilogue instructions
13231 
13232       {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13233        &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13234       {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13235        &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13236       {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13237        &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13238       {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13239        &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13240       {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13241        &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13242       {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13243        &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13244       {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13245        &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13246 
13247       // Supervisor Call (previously Software Interrupt)
13248       {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13249        &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13250 
13251       // If Then makes up to four following instructions conditional.
13252       // The next 5 opcode _must_ come before the if then instruction
13253       {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13254        &EmulateInstructionARM::EmulateNop, "nop"},
13255       {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13256        &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13257       {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13258        &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13259       {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13260        &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13261       {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13262        &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13263       {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13264        &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13265 
13266       // Branch instructions
13267       // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13268       {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13269        &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13270       {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13271        &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13272       {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13273        &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13274       {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13275        &EmulateInstructionARM::EmulateB,
13276        "b<c>.w #imm8 (outside or last in IT)"},
13277       // J1 == J2 == 1
13278       {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13279        &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13280       // J1 == J2 == 1
13281       {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13282        &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13283       {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13284        &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13285       // for example, "bx lr"
13286       {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13287        &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13288       // bxj
13289       {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13290        &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13291       // compare and branch
13292       {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13293        &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13294       // table branch byte
13295       {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13296        &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13297       // table branch halfword
13298       {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13299        &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13300 
13301       // Data-processing instructions
13302       // adc (immediate)
13303       {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13304        &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13305       // adc (register)
13306       {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13307        &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13308       {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13309        &EmulateInstructionARM::EmulateADCReg,
13310        "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13311       // add (register)
13312       {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13313        &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13314       // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13315       // ambiguity decoding the two.
13316       {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13317        &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13318       // adr
13319       {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13320        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13321       {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13322        &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13323       {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13324        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13325       // and (immediate)
13326       {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13327        &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13328       // and (register)
13329       {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13330        &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13331       {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13332        &EmulateInstructionARM::EmulateANDReg,
13333        "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13334       // bic (immediate)
13335       {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13336        &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13337       // bic (register)
13338       {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13339        &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13340       {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13341        &EmulateInstructionARM::EmulateBICReg,
13342        "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13343       // eor (immediate)
13344       {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13345        &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13346       // eor (register)
13347       {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13348        &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13349       {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13350        &EmulateInstructionARM::EmulateEORReg,
13351        "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13352       // orr (immediate)
13353       {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13354        &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13355       // orr (register)
13356       {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13357        &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13358       {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13359        &EmulateInstructionARM::EmulateORRReg,
13360        "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13361       // rsb (immediate)
13362       {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13363        &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13364       {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13365        &EmulateInstructionARM::EmulateRSBImm,
13366        "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13367       // rsb (register)
13368       {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13369        &EmulateInstructionARM::EmulateRSBReg,
13370        "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13371       // sbc (immediate)
13372       {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13373        &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13374       // sbc (register)
13375       {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13376        &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13377       {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13378        &EmulateInstructionARM::EmulateSBCReg,
13379        "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13380       // add (immediate, Thumb)
13381       {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13382        &EmulateInstructionARM::EmulateADDImmThumb,
13383        "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13384       {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13385        &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13386       {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13387        &EmulateInstructionARM::EmulateADDImmThumb,
13388        "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13389       {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13390        &EmulateInstructionARM::EmulateADDImmThumb,
13391        "addw<c> <Rd>,<Rn>,#<imm12>"},
13392       // sub (immediate, Thumb)
13393       {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13394        &EmulateInstructionARM::EmulateSUBImmThumb,
13395        "subs|sub<c> <Rd>, <Rn> #imm3"},
13396       {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13397        &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13398       {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13399        &EmulateInstructionARM::EmulateSUBImmThumb,
13400        "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13401       {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13402        &EmulateInstructionARM::EmulateSUBImmThumb,
13403        "subw<c> <Rd>, <Rn>, #imm12"},
13404       // sub (sp minus immediate)
13405       {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13406        &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13407       {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13408        &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13409       // sub (register)
13410       {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13411        &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13412       {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13413        &EmulateInstructionARM::EmulateSUBReg,
13414        "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13415       // teq (immediate)
13416       {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13417        &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13418       // teq (register)
13419       {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13420        &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13421       // tst (immediate)
13422       {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13423        &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13424       // tst (register)
13425       {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13426        &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13427       {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13428        &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13429 
13430       // move from high register to high register
13431       {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13432        &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13433       // move from low register to low register
13434       {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13435        &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13436       // mov{s}<c>.w <Rd>, <Rm>
13437       {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13438        &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13439       // move immediate
13440       {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13441        &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13442       {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13443        &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13444       {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13445        &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13446       // mvn (immediate)
13447       {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13448        &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13449       // mvn (register)
13450       {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13451        &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13452       {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13453        &EmulateInstructionARM::EmulateMVNReg,
13454        "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13455       // cmn (immediate)
13456       {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13457        &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13458       // cmn (register)
13459       {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13460        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13461       {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13462        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13463       // cmp (immediate)
13464       {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13465        &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13466       {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13467        &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13468       // cmp (register) (Rn and Rm both from r0-r7)
13469       {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13470        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13471       // cmp (register) (Rn and Rm not both from r0-r7)
13472       {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13473        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13474       {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13475        &EmulateInstructionARM::EmulateCMPReg,
13476        "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13477       // asr (immediate)
13478       {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13479        &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13480       {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13481        &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13482       // asr (register)
13483       {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13484        &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13485       {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13486        &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13487       // lsl (immediate)
13488       {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13489        &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13490       {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13491        &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13492       // lsl (register)
13493       {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13494        &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13495       {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13496        &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13497       // lsr (immediate)
13498       {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13499        &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13500       {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13501        &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13502       // lsr (register)
13503       {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13504        &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13505       {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13506        &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13507       // rrx is a special case encoding of ror (immediate)
13508       {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13509        &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13510       // ror (immediate)
13511       {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13512        &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13513       // ror (register)
13514       {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13515        &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13516       {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13517        &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13518       // mul
13519       {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13520        &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13521       // mul
13522       {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13523        &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13524 
13525       // subs pc, lr and related instructions
13526       {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13527        &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13528 
13529       // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13530       // LDM.. Instructions in this table;
13531       // otherwise the wrong instructions will be selected.
13532 
13533       {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13534        &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13535       {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13536        &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13537 
13538       // Load instructions
13539       {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13540        &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13541       {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13542        &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13543       {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13544        &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13545       {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13546        &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13547       {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13548        &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13549       {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13550        &EmulateInstructionARM::EmulateLDRRtRnImm,
13551        "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13552       {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13553        &EmulateInstructionARM::EmulateLDRRtRnImm,
13554        "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13555       // Thumb2 PC-relative load into register
13556       {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13557        &EmulateInstructionARM::EmulateLDRRtPCRelative,
13558        "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13559       {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13560        &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13561       {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13562        &EmulateInstructionARM::EmulateLDRRegister,
13563        "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13564       {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13565        &EmulateInstructionARM::EmulateLDRBImmediate,
13566        "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13567       {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13568        &EmulateInstructionARM::EmulateLDRBImmediate,
13569        "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13570       {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13571        &EmulateInstructionARM::EmulateLDRBImmediate,
13572        "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13573       {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13574        &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13575       {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13576        &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13577       {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13578        &EmulateInstructionARM::EmulateLDRBRegister,
13579        "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13580       {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13581        &EmulateInstructionARM::EmulateLDRHImmediate,
13582        "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13583       {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13584        &EmulateInstructionARM::EmulateLDRHImmediate,
13585        "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13586       {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13587        &EmulateInstructionARM::EmulateLDRHImmediate,
13588        "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13589       {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13590        &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13591       {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13592        &EmulateInstructionARM::EmulateLDRHRegister,
13593        "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13594       {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13595        &EmulateInstructionARM::EmulateLDRHRegister,
13596        "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13597       {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13598        &EmulateInstructionARM::EmulateLDRSBImmediate,
13599        "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13600       {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13601        &EmulateInstructionARM::EmulateLDRSBImmediate,
13602        "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13603       {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13604        &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13605       {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13606        &EmulateInstructionARM::EmulateLDRSBRegister,
13607        "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13608       {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13609        &EmulateInstructionARM::EmulateLDRSBRegister,
13610        "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13611       {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13612        &EmulateInstructionARM::EmulateLDRSHImmediate,
13613        "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13614       {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13615        &EmulateInstructionARM::EmulateLDRSHImmediate,
13616        "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13617       {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13618        &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13619       {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13620        &EmulateInstructionARM::EmulateLDRSHRegister,
13621        "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13622       {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13623        &EmulateInstructionARM::EmulateLDRSHRegister,
13624        "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13625       {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13626        &EmulateInstructionARM::EmulateLDRDImmediate,
13627        "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13628       {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13629        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13630       {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13631        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13632       {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13633        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13634       {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13635        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13636       {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13637        &EmulateInstructionARM::EmulateVLD1Multiple,
13638        "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13639       {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13640        &EmulateInstructionARM::EmulateVLD1Single,
13641        "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13642       {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13643        &EmulateInstructionARM::EmulateVLD1SingleAll,
13644        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13645 
13646       // Store instructions
13647       {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13648        &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13649       {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13650        &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13651       {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13652        &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13653       {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13654        &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13655       {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13656        &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13657       {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13658        &EmulateInstructionARM::EmulateSTRThumb,
13659        "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13660       {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13661        &EmulateInstructionARM::EmulateSTRThumb,
13662        "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13663       {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13664        &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13665       {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13666        &EmulateInstructionARM::EmulateSTRRegister,
13667        "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13668       {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13669        &EmulateInstructionARM::EmulateSTRBThumb,
13670        "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13671       {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13672        &EmulateInstructionARM::EmulateSTRBThumb,
13673        "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13674       {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13675        &EmulateInstructionARM::EmulateSTRBThumb,
13676        "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13677       {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13678        &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13679       {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13680        &EmulateInstructionARM::EmulateSTRHRegister,
13681        "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13682       {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13683        &EmulateInstructionARM::EmulateSTREX,
13684        "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13685       {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13686        &EmulateInstructionARM::EmulateSTRDImm,
13687        "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13688       {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13689        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13690       {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13691        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13692       {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13693        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13694       {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13695        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13696       {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13697        &EmulateInstructionARM::EmulateVST1Multiple,
13698        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13699       {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13700        &EmulateInstructionARM::EmulateVST1Single,
13701        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13702 
13703       // Other instructions
13704       {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13705        &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13706       {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13707        &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13708       {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13709        &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13710       {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13711        &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13712       {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13713        &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13714       {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13715        &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13716       {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13717        &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13718       {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13719        &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13720   };
13721 
13722   const size_t k_num_thumb_opcodes = std::size(g_thumb_opcodes);
13723   for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13724     if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13725         (g_thumb_opcodes[i].variants & arm_isa) != 0)
13726       return &g_thumb_opcodes[i];
13727   }
13728   return nullptr;
13729 }
13730 
SetArchitecture(const ArchSpec & arch)13731 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13732   m_arch = arch;
13733   m_arm_isa = 0;
13734   llvm::StringRef arch_cstr = arch.GetArchitectureName();
13735   if (arch_cstr.equals_insensitive("armv4t"))
13736     m_arm_isa = ARMv4T;
13737   else if (arch_cstr.equals_insensitive("armv5tej"))
13738     m_arm_isa = ARMv5TEJ;
13739   else if (arch_cstr.equals_insensitive("armv5te"))
13740     m_arm_isa = ARMv5TE;
13741   else if (arch_cstr.equals_insensitive("armv5t"))
13742     m_arm_isa = ARMv5T;
13743   else if (arch_cstr.equals_insensitive("armv6k"))
13744     m_arm_isa = ARMv6K;
13745   else if (arch_cstr.equals_insensitive("armv6t2"))
13746     m_arm_isa = ARMv6T2;
13747   else if (arch_cstr.equals_insensitive("armv7s"))
13748     m_arm_isa = ARMv7S;
13749   else if (arch_cstr.equals_insensitive("arm"))
13750     m_arm_isa = ARMvAll;
13751   else if (arch_cstr.equals_insensitive("thumb"))
13752     m_arm_isa = ARMvAll;
13753   else if (arch_cstr.starts_with_insensitive("armv4"))
13754     m_arm_isa = ARMv4;
13755   else if (arch_cstr.starts_with_insensitive("armv6"))
13756     m_arm_isa = ARMv6;
13757   else if (arch_cstr.starts_with_insensitive("armv7"))
13758     m_arm_isa = ARMv7;
13759   else if (arch_cstr.starts_with_insensitive("armv8"))
13760     m_arm_isa = ARMv8;
13761   return m_arm_isa != 0;
13762 }
13763 
SetInstruction(const Opcode & insn_opcode,const Address & inst_addr,Target * target)13764 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13765                                            const Address &inst_addr,
13766                                            Target *target) {
13767   if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13768     if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13769         m_arch.IsAlwaysThumbInstructions())
13770       m_opcode_mode = eModeThumb;
13771     else {
13772       AddressClass addr_class = inst_addr.GetAddressClass();
13773 
13774       if ((addr_class == AddressClass::eCode) ||
13775           (addr_class == AddressClass::eUnknown))
13776         m_opcode_mode = eModeARM;
13777       else if (addr_class == AddressClass::eCodeAlternateISA)
13778         m_opcode_mode = eModeThumb;
13779       else
13780         return false;
13781     }
13782     if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13783       m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13784     else
13785       m_opcode_cpsr = CPSR_MODE_USR;
13786     return true;
13787   }
13788   return false;
13789 }
13790 
ReadInstruction()13791 bool EmulateInstructionARM::ReadInstruction() {
13792   bool success = false;
13793   m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13794                                        LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13795   if (success) {
13796     addr_t pc =
13797         ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13798                              LLDB_INVALID_ADDRESS, &success);
13799     if (success) {
13800       Context read_inst_context;
13801       read_inst_context.type = eContextReadOpcode;
13802       read_inst_context.SetNoArgs();
13803 
13804       if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13805         m_opcode_mode = eModeThumb;
13806         uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13807 
13808         if (success) {
13809           if ((thumb_opcode & 0xe000) != 0xe000 ||
13810               ((thumb_opcode & 0x1800u) == 0)) {
13811             m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13812           } else {
13813             m_opcode.SetOpcode32(
13814                 (thumb_opcode << 16) |
13815                     MemARead(read_inst_context, pc + 2, 2, 0, &success),
13816                 GetByteOrder());
13817           }
13818         }
13819       } else {
13820         m_opcode_mode = eModeARM;
13821         m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13822                              GetByteOrder());
13823       }
13824 
13825       if (!m_ignore_conditions) {
13826         // If we are not ignoreing the conditions then init the it session from
13827         // the current value of cpsr.
13828         uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13829                       Bits32(m_opcode_cpsr, 26, 25);
13830         if (it != 0)
13831           m_it_session.InitIT(it);
13832       }
13833     }
13834   }
13835   if (!success) {
13836     m_opcode_mode = eModeInvalid;
13837     m_addr = LLDB_INVALID_ADDRESS;
13838   }
13839   return success;
13840 }
13841 
ArchVersion()13842 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13843 
ConditionPassed(const uint32_t opcode)13844 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13845   // If we are ignoring conditions, then always return true. this allows us to
13846   // iterate over disassembly code and still emulate an instruction even if we
13847   // don't have all the right bits set in the CPSR register...
13848   if (m_ignore_conditions)
13849     return true;
13850 
13851   const uint32_t cond = CurrentCond(opcode);
13852   if (cond == UINT32_MAX)
13853     return false;
13854 
13855   bool result = false;
13856   switch (UnsignedBits(cond, 3, 1)) {
13857   case 0:
13858     if (m_opcode_cpsr == 0)
13859       result = true;
13860     else
13861       result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13862     break;
13863   case 1:
13864     if (m_opcode_cpsr == 0)
13865       result = true;
13866     else
13867       result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13868     break;
13869   case 2:
13870     if (m_opcode_cpsr == 0)
13871       result = true;
13872     else
13873       result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13874     break;
13875   case 3:
13876     if (m_opcode_cpsr == 0)
13877       result = true;
13878     else
13879       result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13880     break;
13881   case 4:
13882     if (m_opcode_cpsr == 0)
13883       result = true;
13884     else
13885       result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13886                ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13887     break;
13888   case 5:
13889     if (m_opcode_cpsr == 0)
13890       result = true;
13891     else {
13892       bool n = (m_opcode_cpsr & MASK_CPSR_N);
13893       bool v = (m_opcode_cpsr & MASK_CPSR_V);
13894       result = n == v;
13895     }
13896     break;
13897   case 6:
13898     if (m_opcode_cpsr == 0)
13899       result = true;
13900     else {
13901       bool n = (m_opcode_cpsr & MASK_CPSR_N);
13902       bool v = (m_opcode_cpsr & MASK_CPSR_V);
13903       result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13904     }
13905     break;
13906   case 7:
13907     // Always execute (cond == 0b1110, or the special 0b1111 which gives
13908     // opcodes different meanings, but always means execution happens.
13909     return true;
13910   }
13911 
13912   if (cond & 1)
13913     result = !result;
13914   return result;
13915 }
13916 
CurrentCond(const uint32_t opcode)13917 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13918   switch (m_opcode_mode) {
13919   case eModeInvalid:
13920     break;
13921 
13922   case eModeARM:
13923     return UnsignedBits(opcode, 31, 28);
13924 
13925   case eModeThumb:
13926     // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13927     // 'cond' field of the encoding.
13928     {
13929       const uint32_t byte_size = m_opcode.GetByteSize();
13930       if (byte_size == 2) {
13931         if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13932           return Bits32(opcode, 11, 8);
13933       } else if (byte_size == 4) {
13934         if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13935             Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13936           return Bits32(opcode, 25, 22);
13937         }
13938       } else
13939         // We have an invalid thumb instruction, let's bail out.
13940         break;
13941 
13942       return m_it_session.GetCond();
13943     }
13944   }
13945   return UINT32_MAX; // Return invalid value
13946 }
13947 
InITBlock()13948 bool EmulateInstructionARM::InITBlock() {
13949   return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13950 }
13951 
LastInITBlock()13952 bool EmulateInstructionARM::LastInITBlock() {
13953   return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13954 }
13955 
BadMode(uint32_t mode)13956 bool EmulateInstructionARM::BadMode(uint32_t mode) {
13957 
13958   switch (mode) {
13959   case 16:
13960     return false; // '10000'
13961   case 17:
13962     return false; // '10001'
13963   case 18:
13964     return false; // '10010'
13965   case 19:
13966     return false; // '10011'
13967   case 22:
13968     return false; // '10110'
13969   case 23:
13970     return false; // '10111'
13971   case 27:
13972     return false; // '11011'
13973   case 31:
13974     return false; // '11111'
13975   default:
13976     return true;
13977   }
13978   return true;
13979 }
13980 
CurrentModeIsPrivileged()13981 bool EmulateInstructionARM::CurrentModeIsPrivileged() {
13982   uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
13983 
13984   if (BadMode(mode))
13985     return false;
13986 
13987   if (mode == 16)
13988     return false;
13989 
13990   return true;
13991 }
13992 
CPSRWriteByInstr(uint32_t value,uint32_t bytemask,bool affect_execstate)13993 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
13994                                              bool affect_execstate) {
13995   bool privileged = CurrentModeIsPrivileged();
13996 
13997   uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
13998 
13999   if (BitIsSet(bytemask, 3)) {
14000     tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14001     if (affect_execstate)
14002       tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14003   }
14004 
14005   if (BitIsSet(bytemask, 2)) {
14006     tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14007   }
14008 
14009   if (BitIsSet(bytemask, 1)) {
14010     if (affect_execstate)
14011       tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14012     tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14013     if (privileged)
14014       tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14015   }
14016 
14017   if (BitIsSet(bytemask, 0)) {
14018     if (privileged)
14019       tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14020     if (affect_execstate)
14021       tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14022     if (privileged)
14023       tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14024   }
14025 
14026   m_opcode_cpsr = tmp_cpsr;
14027 }
14028 
BranchWritePC(const Context & context,uint32_t addr)14029 bool EmulateInstructionARM::BranchWritePC(const Context &context,
14030                                           uint32_t addr) {
14031   addr_t target;
14032 
14033   // Check the current instruction set.
14034   if (CurrentInstrSet() == eModeARM)
14035     target = addr & 0xfffffffc;
14036   else
14037     target = addr & 0xfffffffe;
14038 
14039   return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14040                                LLDB_REGNUM_GENERIC_PC, target);
14041 }
14042 
14043 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14044 // inspecting addr.
BXWritePC(Context & context,uint32_t addr)14045 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14046   addr_t target;
14047   // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14048   // we want to record it and issue a WriteRegister callback so the clients can
14049   // track the mode changes accordingly.
14050   bool cpsr_changed = false;
14051 
14052   if (BitIsSet(addr, 0)) {
14053     if (CurrentInstrSet() != eModeThumb) {
14054       SelectInstrSet(eModeThumb);
14055       cpsr_changed = true;
14056     }
14057     target = addr & 0xfffffffe;
14058     context.SetISA(eModeThumb);
14059   } else if (BitIsClear(addr, 1)) {
14060     if (CurrentInstrSet() != eModeARM) {
14061       SelectInstrSet(eModeARM);
14062       cpsr_changed = true;
14063     }
14064     target = addr & 0xfffffffc;
14065     context.SetISA(eModeARM);
14066   } else
14067     return false; // address<1:0> == '10' => UNPREDICTABLE
14068 
14069   if (cpsr_changed) {
14070     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14071                                LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14072       return false;
14073   }
14074   return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14075                                LLDB_REGNUM_GENERIC_PC, target);
14076 }
14077 
14078 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14079 // versions.
LoadWritePC(Context & context,uint32_t addr)14080 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14081   if (ArchVersion() >= ARMv5T)
14082     return BXWritePC(context, addr);
14083   else
14084     return BranchWritePC((const Context)context, addr);
14085 }
14086 
14087 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14088 // versions and current instruction set.
ALUWritePC(Context & context,uint32_t addr)14089 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14090   if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14091     return BXWritePC(context, addr);
14092   else
14093     return BranchWritePC((const Context)context, addr);
14094 }
14095 
CurrentInstrSet()14096 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14097   return m_opcode_mode;
14098 }
14099 
14100 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14101 // ReadInstruction() is performed.  This function has a side effect of updating
14102 // the m_new_inst_cpsr member variable if necessary.
SelectInstrSet(Mode arm_or_thumb)14103 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14104   m_new_inst_cpsr = m_opcode_cpsr;
14105   switch (arm_or_thumb) {
14106   default:
14107     return false;
14108   case eModeARM:
14109     // Clear the T bit.
14110     m_new_inst_cpsr &= ~MASK_CPSR_T;
14111     break;
14112   case eModeThumb:
14113     // Set the T bit.
14114     m_new_inst_cpsr |= MASK_CPSR_T;
14115     break;
14116   }
14117   return true;
14118 }
14119 
14120 // This function returns TRUE if the processor currently provides support for
14121 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14122 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
UnalignedSupport()14123 bool EmulateInstructionARM::UnalignedSupport() {
14124   return (ArchVersion() >= ARMv7);
14125 }
14126 
14127 // The main addition and subtraction instructions can produce status
14128 // information about both unsigned carry and signed overflow conditions.  This
14129 // status information can be used to synthesize multi-word additions and
14130 // subtractions.
14131 EmulateInstructionARM::AddWithCarryResult
AddWithCarry(uint32_t x,uint32_t y,uint8_t carry_in)14132 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14133   uint32_t result;
14134   uint8_t carry_out;
14135   uint8_t overflow;
14136 
14137   uint64_t unsigned_sum = x + y + carry_in;
14138   int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14139 
14140   result = UnsignedBits(unsigned_sum, 31, 0);
14141   //    carry_out = (result == unsigned_sum ? 0 : 1);
14142   overflow = ((int32_t)result == signed_sum ? 0 : 1);
14143 
14144   if (carry_in)
14145     carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14146   else
14147     carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14148 
14149   AddWithCarryResult res = {result, carry_out, overflow};
14150   return res;
14151 }
14152 
ReadCoreReg(uint32_t num,bool * success)14153 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14154   lldb::RegisterKind reg_kind;
14155   uint32_t reg_num;
14156   switch (num) {
14157   case SP_REG:
14158     reg_kind = eRegisterKindGeneric;
14159     reg_num = LLDB_REGNUM_GENERIC_SP;
14160     break;
14161   case LR_REG:
14162     reg_kind = eRegisterKindGeneric;
14163     reg_num = LLDB_REGNUM_GENERIC_RA;
14164     break;
14165   case PC_REG:
14166     reg_kind = eRegisterKindGeneric;
14167     reg_num = LLDB_REGNUM_GENERIC_PC;
14168     break;
14169   default:
14170     if (num < SP_REG) {
14171       reg_kind = eRegisterKindDWARF;
14172       reg_num = dwarf_r0 + num;
14173     } else {
14174       // assert(0 && "Invalid register number");
14175       *success = false;
14176       return UINT32_MAX;
14177     }
14178     break;
14179   }
14180 
14181   // Read our register.
14182   uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14183 
14184   // When executing an ARM instruction , PC reads as the address of the current
14185   // instruction plus 8. When executing a Thumb instruction , PC reads as the
14186   // address of the current instruction plus 4.
14187   if (num == 15) {
14188     if (CurrentInstrSet() == eModeARM)
14189       val += 8;
14190     else
14191       val += 4;
14192   }
14193 
14194   return val;
14195 }
14196 
14197 // Write the result to the ARM core register Rd, and optionally update the
14198 // condition flags based on the result.
14199 //
14200 // This helper method tries to encapsulate the following pseudocode from the
14201 // ARM Architecture Reference Manual:
14202 //
14203 // if d == 15 then         // Can only occur for encoding A1
14204 //     ALUWritePC(result); // setflags is always FALSE here
14205 // else
14206 //     R[d] = result;
14207 //     if setflags then
14208 //         APSR.N = result<31>;
14209 //         APSR.Z = IsZeroBit(result);
14210 //         APSR.C = carry;
14211 //         // APSR.V unchanged
14212 //
14213 // In the above case, the API client does not pass in the overflow arg, which
14214 // defaults to ~0u.
WriteCoreRegOptionalFlags(Context & context,const uint32_t result,const uint32_t Rd,bool setflags,const uint32_t carry,const uint32_t overflow)14215 bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14216     Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14217     const uint32_t carry, const uint32_t overflow) {
14218   if (Rd == 15) {
14219     if (!ALUWritePC(context, result))
14220       return false;
14221   } else {
14222     lldb::RegisterKind reg_kind;
14223     uint32_t reg_num;
14224     switch (Rd) {
14225     case SP_REG:
14226       reg_kind = eRegisterKindGeneric;
14227       reg_num = LLDB_REGNUM_GENERIC_SP;
14228       break;
14229     case LR_REG:
14230       reg_kind = eRegisterKindGeneric;
14231       reg_num = LLDB_REGNUM_GENERIC_RA;
14232       break;
14233     default:
14234       reg_kind = eRegisterKindDWARF;
14235       reg_num = dwarf_r0 + Rd;
14236     }
14237     if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14238       return false;
14239     if (setflags)
14240       return WriteFlags(context, result, carry, overflow);
14241   }
14242   return true;
14243 }
14244 
14245 // This helper method tries to encapsulate the following pseudocode from the
14246 // ARM Architecture Reference Manual:
14247 //
14248 // APSR.N = result<31>;
14249 // APSR.Z = IsZeroBit(result);
14250 // APSR.C = carry;
14251 // APSR.V = overflow
14252 //
14253 // Default arguments can be specified for carry and overflow parameters, which
14254 // means not to update the respective flags.
WriteFlags(Context & context,const uint32_t result,const uint32_t carry,const uint32_t overflow)14255 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14256                                        const uint32_t carry,
14257                                        const uint32_t overflow) {
14258   m_new_inst_cpsr = m_opcode_cpsr;
14259   SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14260   SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14261   if (carry != ~0u)
14262     SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14263   if (overflow != ~0u)
14264     SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14265   if (m_new_inst_cpsr != m_opcode_cpsr) {
14266     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14267                                LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14268       return false;
14269   }
14270   return true;
14271 }
14272 
EvaluateInstruction(uint32_t evaluate_options)14273 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14274   ARMOpcode *opcode_data = nullptr;
14275 
14276   if (m_opcode_mode == eModeThumb)
14277     opcode_data =
14278         GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14279   else if (m_opcode_mode == eModeARM)
14280     opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14281 
14282   const bool auto_advance_pc =
14283       evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14284   m_ignore_conditions =
14285       evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14286 
14287   bool success = false;
14288   if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14289     m_opcode_cpsr =
14290         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14291   }
14292 
14293   // Only return false if we are unable to read the CPSR if we care about
14294   // conditions
14295   if (!success && !m_ignore_conditions)
14296     return false;
14297 
14298   uint32_t orig_pc_value = 0;
14299   if (auto_advance_pc) {
14300     orig_pc_value =
14301         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14302     if (!success)
14303       return false;
14304   }
14305 
14306   // Call the Emulate... function if we managed to decode the opcode.
14307   if (opcode_data) {
14308     success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14309                                              opcode_data->encoding);
14310     if (!success)
14311       return false;
14312   }
14313 
14314   // Advance the ITSTATE bits to their values for the next instruction if we
14315   // haven't just executed an IT instruction what initialized it.
14316   if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14317       (opcode_data == nullptr ||
14318        opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14319     m_it_session.ITAdvance();
14320 
14321   if (auto_advance_pc) {
14322     uint32_t after_pc_value =
14323         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14324     if (!success)
14325       return false;
14326 
14327     if (after_pc_value == orig_pc_value) {
14328       after_pc_value += m_opcode.GetByteSize();
14329 
14330       EmulateInstruction::Context context;
14331       context.type = eContextAdvancePC;
14332       context.SetNoArgs();
14333       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14334                                  after_pc_value))
14335         return false;
14336     }
14337   }
14338   return true;
14339 }
14340 
14341 EmulateInstruction::InstructionCondition
GetInstructionCondition()14342 EmulateInstructionARM::GetInstructionCondition() {
14343   const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14344   if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14345     return EmulateInstruction::UnconditionalCondition;
14346   return cond;
14347 }
14348 
TestEmulation(Stream & out_stream,ArchSpec & arch,OptionValueDictionary * test_data)14349 bool EmulateInstructionARM::TestEmulation(Stream &out_stream, ArchSpec &arch,
14350                                           OptionValueDictionary *test_data) {
14351   if (!test_data) {
14352     out_stream.Printf("TestEmulation: Missing test data.\n");
14353     return false;
14354   }
14355 
14356   static constexpr llvm::StringLiteral opcode_key("opcode");
14357   static constexpr llvm::StringLiteral before_key("before_state");
14358   static constexpr llvm::StringLiteral after_key("after_state");
14359 
14360   OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14361 
14362   uint32_t test_opcode;
14363   if ((value_sp.get() == nullptr) ||
14364       (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14365     out_stream.Printf("TestEmulation: Error reading opcode from test file.\n");
14366     return false;
14367   }
14368   test_opcode = value_sp->GetValueAs<uint64_t>().value_or(0);
14369 
14370   if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14371       arch.IsAlwaysThumbInstructions()) {
14372     m_opcode_mode = eModeThumb;
14373     if (test_opcode < 0x10000)
14374       m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14375     else
14376       m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14377   } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14378     m_opcode_mode = eModeARM;
14379     m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14380   } else {
14381     out_stream.Printf("TestEmulation:  Invalid arch.\n");
14382     return false;
14383   }
14384 
14385   EmulationStateARM before_state;
14386   EmulationStateARM after_state;
14387 
14388   value_sp = test_data->GetValueForKey(before_key);
14389   if ((value_sp.get() == nullptr) ||
14390       (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14391     out_stream.Printf("TestEmulation:  Failed to find 'before' state.\n");
14392     return false;
14393   }
14394 
14395   OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14396   if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14397     out_stream.Printf("TestEmulation:  Failed loading 'before' state.\n");
14398     return false;
14399   }
14400 
14401   value_sp = test_data->GetValueForKey(after_key);
14402   if ((value_sp.get() == nullptr) ||
14403       (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14404     out_stream.Printf("TestEmulation:  Failed to find 'after' state.\n");
14405     return false;
14406   }
14407 
14408   state_dictionary = value_sp->GetAsDictionary();
14409   if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14410     out_stream.Printf("TestEmulation: Failed loading 'after' state.\n");
14411     return false;
14412   }
14413 
14414   SetBaton((void *)&before_state);
14415   SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14416                &EmulationStateARM::WritePseudoMemory,
14417                &EmulationStateARM::ReadPseudoRegister,
14418                &EmulationStateARM::WritePseudoRegister);
14419 
14420   bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14421   if (!success) {
14422     out_stream.Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14423     return false;
14424   }
14425 
14426   success = before_state.CompareState(after_state, out_stream);
14427   if (!success)
14428     out_stream.Printf("TestEmulation:  State after emulation does not match "
14429                       "'after' state.\n");
14430 
14431   return success;
14432 }
14433 //
14434 //
14435 // const char *
14436 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14437 //{
14438 //    if (reg_kind == eRegisterKindGeneric)
14439 //    {
14440 //        switch (reg_num)
14441 //        {
14442 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14443 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14444 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14445 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14446 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14447 //        default: return NULL;
14448 //        }
14449 //    }
14450 //    else if (reg_kind == eRegisterKindDWARF)
14451 //    {
14452 //        return GetARMDWARFRegisterName (reg_num);
14453 //    }
14454 //    return NULL;
14455 //}
14456 //
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)14457 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14458   unwind_plan.Clear();
14459   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14460 
14461   UnwindPlan::RowSP row(new UnwindPlan::Row);
14462 
14463   // Our previous Call Frame Address is the stack pointer
14464   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14465 
14466   unwind_plan.AppendRow(row);
14467   unwind_plan.SetSourceName("EmulateInstructionARM");
14468   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14469   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14470   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
14471   unwind_plan.SetReturnAddressRegister(dwarf_lr);
14472   return true;
14473 }
14474