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 
11 #include "EmulateInstructionARM.h"
12 #include "EmulationStateARM.h"
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Host/PosixApi.h"
16 #include "lldb/Interpreter/OptionValueArray.h"
17 #include "lldb/Interpreter/OptionValueDictionary.h"
18 #include "lldb/Symbol/UnwindPlan.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/ConstString.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 bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo &reg_info) {
46   ::memset(&reg_info, 0, sizeof(RegisterInfo));
47   ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
48 
49   if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
50     reg_info.byte_size = 16;
51     reg_info.format = eFormatVectorOfUInt8;
52     reg_info.encoding = eEncodingVector;
53   }
54 
55   if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
56     reg_info.byte_size = 8;
57     reg_info.format = eFormatFloat;
58     reg_info.encoding = eEncodingIEEE754;
59   } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
60     reg_info.byte_size = 4;
61     reg_info.format = eFormatFloat;
62     reg_info.encoding = eEncodingIEEE754;
63   } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
64     reg_info.byte_size = 12;
65     reg_info.format = eFormatFloat;
66     reg_info.encoding = eEncodingIEEE754;
67   } else {
68     reg_info.byte_size = 4;
69     reg_info.format = eFormatHex;
70     reg_info.encoding = eEncodingUint;
71   }
72 
73   reg_info.kinds[eRegisterKindDWARF] = reg_num;
74 
75   switch (reg_num) {
76   case dwarf_r0:
77     reg_info.name = "r0";
78     break;
79   case dwarf_r1:
80     reg_info.name = "r1";
81     break;
82   case dwarf_r2:
83     reg_info.name = "r2";
84     break;
85   case dwarf_r3:
86     reg_info.name = "r3";
87     break;
88   case dwarf_r4:
89     reg_info.name = "r4";
90     break;
91   case dwarf_r5:
92     reg_info.name = "r5";
93     break;
94   case dwarf_r6:
95     reg_info.name = "r6";
96     break;
97   case dwarf_r7:
98     reg_info.name = "r7";
99     reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
100     break;
101   case dwarf_r8:
102     reg_info.name = "r8";
103     break;
104   case dwarf_r9:
105     reg_info.name = "r9";
106     break;
107   case dwarf_r10:
108     reg_info.name = "r10";
109     break;
110   case dwarf_r11:
111     reg_info.name = "r11";
112     break;
113   case dwarf_r12:
114     reg_info.name = "r12";
115     break;
116   case dwarf_sp:
117     reg_info.name = "sp";
118     reg_info.alt_name = "r13";
119     reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
120     break;
121   case dwarf_lr:
122     reg_info.name = "lr";
123     reg_info.alt_name = "r14";
124     reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
125     break;
126   case dwarf_pc:
127     reg_info.name = "pc";
128     reg_info.alt_name = "r15";
129     reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
130     break;
131   case dwarf_cpsr:
132     reg_info.name = "cpsr";
133     reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
134     break;
135 
136   case dwarf_s0:
137     reg_info.name = "s0";
138     break;
139   case dwarf_s1:
140     reg_info.name = "s1";
141     break;
142   case dwarf_s2:
143     reg_info.name = "s2";
144     break;
145   case dwarf_s3:
146     reg_info.name = "s3";
147     break;
148   case dwarf_s4:
149     reg_info.name = "s4";
150     break;
151   case dwarf_s5:
152     reg_info.name = "s5";
153     break;
154   case dwarf_s6:
155     reg_info.name = "s6";
156     break;
157   case dwarf_s7:
158     reg_info.name = "s7";
159     break;
160   case dwarf_s8:
161     reg_info.name = "s8";
162     break;
163   case dwarf_s9:
164     reg_info.name = "s9";
165     break;
166   case dwarf_s10:
167     reg_info.name = "s10";
168     break;
169   case dwarf_s11:
170     reg_info.name = "s11";
171     break;
172   case dwarf_s12:
173     reg_info.name = "s12";
174     break;
175   case dwarf_s13:
176     reg_info.name = "s13";
177     break;
178   case dwarf_s14:
179     reg_info.name = "s14";
180     break;
181   case dwarf_s15:
182     reg_info.name = "s15";
183     break;
184   case dwarf_s16:
185     reg_info.name = "s16";
186     break;
187   case dwarf_s17:
188     reg_info.name = "s17";
189     break;
190   case dwarf_s18:
191     reg_info.name = "s18";
192     break;
193   case dwarf_s19:
194     reg_info.name = "s19";
195     break;
196   case dwarf_s20:
197     reg_info.name = "s20";
198     break;
199   case dwarf_s21:
200     reg_info.name = "s21";
201     break;
202   case dwarf_s22:
203     reg_info.name = "s22";
204     break;
205   case dwarf_s23:
206     reg_info.name = "s23";
207     break;
208   case dwarf_s24:
209     reg_info.name = "s24";
210     break;
211   case dwarf_s25:
212     reg_info.name = "s25";
213     break;
214   case dwarf_s26:
215     reg_info.name = "s26";
216     break;
217   case dwarf_s27:
218     reg_info.name = "s27";
219     break;
220   case dwarf_s28:
221     reg_info.name = "s28";
222     break;
223   case dwarf_s29:
224     reg_info.name = "s29";
225     break;
226   case dwarf_s30:
227     reg_info.name = "s30";
228     break;
229   case dwarf_s31:
230     reg_info.name = "s31";
231     break;
232 
233   // FPA Registers 0-7
234   case dwarf_f0:
235     reg_info.name = "f0";
236     break;
237   case dwarf_f1:
238     reg_info.name = "f1";
239     break;
240   case dwarf_f2:
241     reg_info.name = "f2";
242     break;
243   case dwarf_f3:
244     reg_info.name = "f3";
245     break;
246   case dwarf_f4:
247     reg_info.name = "f4";
248     break;
249   case dwarf_f5:
250     reg_info.name = "f5";
251     break;
252   case dwarf_f6:
253     reg_info.name = "f6";
254     break;
255   case dwarf_f7:
256     reg_info.name = "f7";
257     break;
258 
259   // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
260   // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
261   case dwarf_wCGR0:
262     reg_info.name = "wCGR0/ACC0";
263     break;
264   case dwarf_wCGR1:
265     reg_info.name = "wCGR1/ACC1";
266     break;
267   case dwarf_wCGR2:
268     reg_info.name = "wCGR2/ACC2";
269     break;
270   case dwarf_wCGR3:
271     reg_info.name = "wCGR3/ACC3";
272     break;
273   case dwarf_wCGR4:
274     reg_info.name = "wCGR4/ACC4";
275     break;
276   case dwarf_wCGR5:
277     reg_info.name = "wCGR5/ACC5";
278     break;
279   case dwarf_wCGR6:
280     reg_info.name = "wCGR6/ACC6";
281     break;
282   case dwarf_wCGR7:
283     reg_info.name = "wCGR7/ACC7";
284     break;
285 
286   // Intel wireless MMX data registers 0 - 15
287   case dwarf_wR0:
288     reg_info.name = "wR0";
289     break;
290   case dwarf_wR1:
291     reg_info.name = "wR1";
292     break;
293   case dwarf_wR2:
294     reg_info.name = "wR2";
295     break;
296   case dwarf_wR3:
297     reg_info.name = "wR3";
298     break;
299   case dwarf_wR4:
300     reg_info.name = "wR4";
301     break;
302   case dwarf_wR5:
303     reg_info.name = "wR5";
304     break;
305   case dwarf_wR6:
306     reg_info.name = "wR6";
307     break;
308   case dwarf_wR7:
309     reg_info.name = "wR7";
310     break;
311   case dwarf_wR8:
312     reg_info.name = "wR8";
313     break;
314   case dwarf_wR9:
315     reg_info.name = "wR9";
316     break;
317   case dwarf_wR10:
318     reg_info.name = "wR10";
319     break;
320   case dwarf_wR11:
321     reg_info.name = "wR11";
322     break;
323   case dwarf_wR12:
324     reg_info.name = "wR12";
325     break;
326   case dwarf_wR13:
327     reg_info.name = "wR13";
328     break;
329   case dwarf_wR14:
330     reg_info.name = "wR14";
331     break;
332   case dwarf_wR15:
333     reg_info.name = "wR15";
334     break;
335 
336   case dwarf_spsr:
337     reg_info.name = "spsr";
338     break;
339   case dwarf_spsr_fiq:
340     reg_info.name = "spsr_fiq";
341     break;
342   case dwarf_spsr_irq:
343     reg_info.name = "spsr_irq";
344     break;
345   case dwarf_spsr_abt:
346     reg_info.name = "spsr_abt";
347     break;
348   case dwarf_spsr_und:
349     reg_info.name = "spsr_und";
350     break;
351   case dwarf_spsr_svc:
352     reg_info.name = "spsr_svc";
353     break;
354 
355   case dwarf_r8_usr:
356     reg_info.name = "r8_usr";
357     break;
358   case dwarf_r9_usr:
359     reg_info.name = "r9_usr";
360     break;
361   case dwarf_r10_usr:
362     reg_info.name = "r10_usr";
363     break;
364   case dwarf_r11_usr:
365     reg_info.name = "r11_usr";
366     break;
367   case dwarf_r12_usr:
368     reg_info.name = "r12_usr";
369     break;
370   case dwarf_r13_usr:
371     reg_info.name = "r13_usr";
372     break;
373   case dwarf_r14_usr:
374     reg_info.name = "r14_usr";
375     break;
376   case dwarf_r8_fiq:
377     reg_info.name = "r8_fiq";
378     break;
379   case dwarf_r9_fiq:
380     reg_info.name = "r9_fiq";
381     break;
382   case dwarf_r10_fiq:
383     reg_info.name = "r10_fiq";
384     break;
385   case dwarf_r11_fiq:
386     reg_info.name = "r11_fiq";
387     break;
388   case dwarf_r12_fiq:
389     reg_info.name = "r12_fiq";
390     break;
391   case dwarf_r13_fiq:
392     reg_info.name = "r13_fiq";
393     break;
394   case dwarf_r14_fiq:
395     reg_info.name = "r14_fiq";
396     break;
397   case dwarf_r13_irq:
398     reg_info.name = "r13_irq";
399     break;
400   case dwarf_r14_irq:
401     reg_info.name = "r14_irq";
402     break;
403   case dwarf_r13_abt:
404     reg_info.name = "r13_abt";
405     break;
406   case dwarf_r14_abt:
407     reg_info.name = "r14_abt";
408     break;
409   case dwarf_r13_und:
410     reg_info.name = "r13_und";
411     break;
412   case dwarf_r14_und:
413     reg_info.name = "r14_und";
414     break;
415   case dwarf_r13_svc:
416     reg_info.name = "r13_svc";
417     break;
418   case dwarf_r14_svc:
419     reg_info.name = "r14_svc";
420     break;
421 
422   // Intel wireless MMX control register in co-processor 0 - 7
423   case dwarf_wC0:
424     reg_info.name = "wC0";
425     break;
426   case dwarf_wC1:
427     reg_info.name = "wC1";
428     break;
429   case dwarf_wC2:
430     reg_info.name = "wC2";
431     break;
432   case dwarf_wC3:
433     reg_info.name = "wC3";
434     break;
435   case dwarf_wC4:
436     reg_info.name = "wC4";
437     break;
438   case dwarf_wC5:
439     reg_info.name = "wC5";
440     break;
441   case dwarf_wC6:
442     reg_info.name = "wC6";
443     break;
444   case dwarf_wC7:
445     reg_info.name = "wC7";
446     break;
447 
448   // VFP-v3/Neon
449   case dwarf_d0:
450     reg_info.name = "d0";
451     break;
452   case dwarf_d1:
453     reg_info.name = "d1";
454     break;
455   case dwarf_d2:
456     reg_info.name = "d2";
457     break;
458   case dwarf_d3:
459     reg_info.name = "d3";
460     break;
461   case dwarf_d4:
462     reg_info.name = "d4";
463     break;
464   case dwarf_d5:
465     reg_info.name = "d5";
466     break;
467   case dwarf_d6:
468     reg_info.name = "d6";
469     break;
470   case dwarf_d7:
471     reg_info.name = "d7";
472     break;
473   case dwarf_d8:
474     reg_info.name = "d8";
475     break;
476   case dwarf_d9:
477     reg_info.name = "d9";
478     break;
479   case dwarf_d10:
480     reg_info.name = "d10";
481     break;
482   case dwarf_d11:
483     reg_info.name = "d11";
484     break;
485   case dwarf_d12:
486     reg_info.name = "d12";
487     break;
488   case dwarf_d13:
489     reg_info.name = "d13";
490     break;
491   case dwarf_d14:
492     reg_info.name = "d14";
493     break;
494   case dwarf_d15:
495     reg_info.name = "d15";
496     break;
497   case dwarf_d16:
498     reg_info.name = "d16";
499     break;
500   case dwarf_d17:
501     reg_info.name = "d17";
502     break;
503   case dwarf_d18:
504     reg_info.name = "d18";
505     break;
506   case dwarf_d19:
507     reg_info.name = "d19";
508     break;
509   case dwarf_d20:
510     reg_info.name = "d20";
511     break;
512   case dwarf_d21:
513     reg_info.name = "d21";
514     break;
515   case dwarf_d22:
516     reg_info.name = "d22";
517     break;
518   case dwarf_d23:
519     reg_info.name = "d23";
520     break;
521   case dwarf_d24:
522     reg_info.name = "d24";
523     break;
524   case dwarf_d25:
525     reg_info.name = "d25";
526     break;
527   case dwarf_d26:
528     reg_info.name = "d26";
529     break;
530   case dwarf_d27:
531     reg_info.name = "d27";
532     break;
533   case dwarf_d28:
534     reg_info.name = "d28";
535     break;
536   case dwarf_d29:
537     reg_info.name = "d29";
538     break;
539   case dwarf_d30:
540     reg_info.name = "d30";
541     break;
542   case dwarf_d31:
543     reg_info.name = "d31";
544     break;
545 
546   // NEON 128-bit vector registers (overlays the d registers)
547   case dwarf_q0:
548     reg_info.name = "q0";
549     break;
550   case dwarf_q1:
551     reg_info.name = "q1";
552     break;
553   case dwarf_q2:
554     reg_info.name = "q2";
555     break;
556   case dwarf_q3:
557     reg_info.name = "q3";
558     break;
559   case dwarf_q4:
560     reg_info.name = "q4";
561     break;
562   case dwarf_q5:
563     reg_info.name = "q5";
564     break;
565   case dwarf_q6:
566     reg_info.name = "q6";
567     break;
568   case dwarf_q7:
569     reg_info.name = "q7";
570     break;
571   case dwarf_q8:
572     reg_info.name = "q8";
573     break;
574   case dwarf_q9:
575     reg_info.name = "q9";
576     break;
577   case dwarf_q10:
578     reg_info.name = "q10";
579     break;
580   case dwarf_q11:
581     reg_info.name = "q11";
582     break;
583   case dwarf_q12:
584     reg_info.name = "q12";
585     break;
586   case dwarf_q13:
587     reg_info.name = "q13";
588     break;
589   case dwarf_q14:
590     reg_info.name = "q14";
591     break;
592   case dwarf_q15:
593     reg_info.name = "q15";
594     break;
595 
596   default:
597     return false;
598   }
599   return true;
600 }
601 
602 // A8.6.50
603 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
CountITSize(uint32_t ITMask)604 static uint32_t CountITSize(uint32_t ITMask) {
605   // First count the trailing zeros of the IT mask.
606   uint32_t TZ = llvm::countTrailingZeros(ITMask);
607   if (TZ > 3) {
608     return 0;
609   }
610   return (4 - TZ);
611 }
612 
613 // Init ITState.  Note that at least one bit is always 1 in mask.
InitIT(uint32_t bits7_0)614 bool ITSession::InitIT(uint32_t bits7_0) {
615   ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
616   if (ITCounter == 0)
617     return false;
618 
619   // A8.6.50 IT
620   unsigned short FirstCond = Bits32(bits7_0, 7, 4);
621   if (FirstCond == 0xF) {
622     return false;
623   }
624   if (FirstCond == 0xE && ITCounter != 1) {
625     return false;
626   }
627 
628   ITState = bits7_0;
629   return true;
630 }
631 
632 // Update ITState if necessary.
ITAdvance()633 void ITSession::ITAdvance() {
634   // assert(ITCounter);
635   --ITCounter;
636   if (ITCounter == 0)
637     ITState = 0;
638   else {
639     unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
640     SetBits32(ITState, 4, 0, NewITState4_0);
641   }
642 }
643 
644 // Return true if we're inside an IT Block.
InITBlock()645 bool ITSession::InITBlock() { return ITCounter != 0; }
646 
647 // Return true if we're the last instruction inside an IT Block.
LastInITBlock()648 bool ITSession::LastInITBlock() { return ITCounter == 1; }
649 
650 // Get condition bits for the current thumb instruction.
GetCond()651 uint32_t ITSession::GetCond() {
652   if (InITBlock())
653     return Bits32(ITState, 7, 4);
654   else
655     return COND_AL;
656 }
657 
658 // ARM constants used during decoding
659 #define REG_RD 0
660 #define LDM_REGLIST 1
661 #define SP_REG 13
662 #define LR_REG 14
663 #define PC_REG 15
664 #define PC_REGLIST_BIT 0x8000
665 
666 #define ARMv4 (1u << 0)
667 #define ARMv4T (1u << 1)
668 #define ARMv5T (1u << 2)
669 #define ARMv5TE (1u << 3)
670 #define ARMv5TEJ (1u << 4)
671 #define ARMv6 (1u << 5)
672 #define ARMv6K (1u << 6)
673 #define ARMv6T2 (1u << 7)
674 #define ARMv7 (1u << 8)
675 #define ARMv7S (1u << 9)
676 #define ARMv8 (1u << 10)
677 #define ARMvAll (0xffffffffu)
678 
679 #define ARMV4T_ABOVE                                                           \
680   (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 |   \
681    ARMv7S | ARMv8)
682 #define ARMV5_ABOVE                                                            \
683   (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S |   \
684    ARMv8)
685 #define ARMV5TE_ABOVE                                                          \
686   (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
687 #define ARMV5J_ABOVE                                                           \
688   (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
689 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
690 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
691 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
692 
693 #define No_VFP 0
694 #define VFPv1 (1u << 1)
695 #define VFPv2 (1u << 2)
696 #define VFPv3 (1u << 3)
697 #define AdvancedSIMD (1u << 4)
698 
699 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
700 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
701 #define VFPv2v3 (VFPv2 | VFPv3)
702 
703 //
704 // EmulateInstructionARM implementation
705 //
706 
Initialize()707 void EmulateInstructionARM::Initialize() {
708   PluginManager::RegisterPlugin(GetPluginNameStatic(),
709                                 GetPluginDescriptionStatic(), CreateInstance);
710 }
711 
Terminate()712 void EmulateInstructionARM::Terminate() {
713   PluginManager::UnregisterPlugin(CreateInstance);
714 }
715 
GetPluginNameStatic()716 ConstString EmulateInstructionARM::GetPluginNameStatic() {
717   static ConstString g_name("arm");
718   return g_name;
719 }
720 
GetPluginDescriptionStatic()721 const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
722   return "Emulate instructions for the ARM architecture.";
723 }
724 
725 EmulateInstruction *
CreateInstance(const ArchSpec & arch,InstructionType inst_type)726 EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
727                                       InstructionType inst_type) {
728   if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
729           inst_type)) {
730     if (arch.GetTriple().getArch() == llvm::Triple::arm) {
731       std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
732           new EmulateInstructionARM(arch));
733 
734       if (emulate_insn_up)
735         return emulate_insn_up.release();
736     } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
737       std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
738           new EmulateInstructionARM(arch));
739 
740       if (emulate_insn_up)
741         return emulate_insn_up.release();
742     }
743   }
744 
745   return nullptr;
746 }
747 
SetTargetTriple(const ArchSpec & arch)748 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
749   if (arch.GetTriple().getArch() == llvm::Triple::arm)
750     return true;
751   else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
752     return true;
753 
754   return false;
755 }
756 
757 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for
758 // many ARM instructions.
WriteBits32UnknownToMemory(addr_t address)759 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
760   EmulateInstruction::Context context;
761   context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
762   context.SetNoArgs();
763 
764   uint32_t random_data = rand();
765   const uint32_t addr_byte_size = GetAddressByteSize();
766 
767   return MemAWrite(context, address, random_data, addr_byte_size);
768 }
769 
770 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM
771 // instructions.
WriteBits32Unknown(int n)772 bool EmulateInstructionARM::WriteBits32Unknown(int n) {
773   EmulateInstruction::Context context;
774   context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
775   context.SetNoArgs();
776 
777   bool success;
778   uint32_t data =
779       ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
780 
781   if (!success)
782     return false;
783 
784   if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
785     return false;
786 
787   return true;
788 }
789 
GetRegisterInfo(lldb::RegisterKind reg_kind,uint32_t reg_num,RegisterInfo & reg_info)790 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
791                                             uint32_t reg_num,
792                                             RegisterInfo &reg_info) {
793   if (reg_kind == eRegisterKindGeneric) {
794     switch (reg_num) {
795     case LLDB_REGNUM_GENERIC_PC:
796       reg_kind = eRegisterKindDWARF;
797       reg_num = dwarf_pc;
798       break;
799     case LLDB_REGNUM_GENERIC_SP:
800       reg_kind = eRegisterKindDWARF;
801       reg_num = dwarf_sp;
802       break;
803     case LLDB_REGNUM_GENERIC_FP:
804       reg_kind = eRegisterKindDWARF;
805       reg_num = dwarf_r7;
806       break;
807     case LLDB_REGNUM_GENERIC_RA:
808       reg_kind = eRegisterKindDWARF;
809       reg_num = dwarf_lr;
810       break;
811     case LLDB_REGNUM_GENERIC_FLAGS:
812       reg_kind = eRegisterKindDWARF;
813       reg_num = dwarf_cpsr;
814       break;
815     default:
816       return false;
817     }
818   }
819 
820   if (reg_kind == eRegisterKindDWARF)
821     return GetARMDWARFRegisterInfo(reg_num, reg_info);
822   return false;
823 }
824 
GetFramePointerRegisterNumber() const825 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
826   if (m_arch.GetTriple().isAndroid())
827     return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
828   bool is_apple = false;
829   if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
830     is_apple = true;
831   switch (m_arch.GetTriple().getOS()) {
832   case llvm::Triple::Darwin:
833   case llvm::Triple::MacOSX:
834   case llvm::Triple::IOS:
835   case llvm::Triple::TvOS:
836   case llvm::Triple::WatchOS:
837   // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
838     is_apple = true;
839     break;
840   default:
841     break;
842   }
843 
844   /* On Apple iOS et al, the frame pointer register is always r7.
845    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
846    * Windows on ARM, which is in thumb mode, uses r11 though.
847    */
848 
849   uint32_t fp_regnum = 11;
850 
851   if (is_apple)
852     fp_regnum = 7;
853 
854   if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
855     fp_regnum = 7;
856 
857   return fp_regnum;
858 }
859 
GetFramePointerDWARFRegisterNumber() const860 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
861   bool is_apple = false;
862   if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
863     is_apple = true;
864   switch (m_arch.GetTriple().getOS()) {
865   case llvm::Triple::Darwin:
866   case llvm::Triple::MacOSX:
867   case llvm::Triple::IOS:
868     is_apple = true;
869     break;
870   default:
871     break;
872   }
873 
874   /* On Apple iOS et al, the frame pointer register is always r7.
875    * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
876    * Windows on ARM, which is in thumb mode, uses r11 though.
877    */
878 
879   uint32_t fp_regnum = dwarf_r11;
880 
881   if (is_apple)
882     fp_regnum = dwarf_r7;
883 
884   if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows())
885     fp_regnum = dwarf_r7;
886 
887   return fp_regnum;
888 }
889 
890 // Push Multiple Registers stores multiple registers to the stack, storing to
891 // consecutive memory locations ending just below the address in SP, and
892 // updates
893 // SP to point to the start of the stored data.
EmulatePUSH(const uint32_t opcode,const ARMEncoding encoding)894 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
895                                         const ARMEncoding encoding) {
896 #if 0
897     // ARM pseudo code...
898     if (ConditionPassed())
899     {
900         EncodingSpecificOperations();
901         NullCheckIfThumbEE(13);
902         address = SP - 4*BitCount(registers);
903 
904         for (i = 0 to 14)
905         {
906             if (registers<i> == '1')
907             {
908                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
909                     MemA[address,4] = bits(32) UNKNOWN;
910                 else
911                     MemA[address,4] = R[i];
912                 address = address + 4;
913             }
914         }
915 
916         if (registers<15> == '1') // Only possible for encoding A1 or A2
917             MemA[address,4] = PCStoreValue();
918 
919         SP = SP - 4*BitCount(registers);
920     }
921 #endif
922 
923   bool success = false;
924   if (ConditionPassed(opcode)) {
925     const uint32_t addr_byte_size = GetAddressByteSize();
926     const addr_t sp = ReadCoreReg(SP_REG, &success);
927     if (!success)
928       return false;
929     uint32_t registers = 0;
930     uint32_t Rt; // the source register
931     switch (encoding) {
932     case eEncodingT1:
933       registers = Bits32(opcode, 7, 0);
934       // The M bit represents LR.
935       if (Bit32(opcode, 8))
936         registers |= (1u << 14);
937       // if BitCount(registers) < 1 then UNPREDICTABLE;
938       if (BitCount(registers) < 1)
939         return false;
940       break;
941     case eEncodingT2:
942       // Ignore bits 15 & 13.
943       registers = Bits32(opcode, 15, 0) & ~0xa000;
944       // if BitCount(registers) < 2 then UNPREDICTABLE;
945       if (BitCount(registers) < 2)
946         return false;
947       break;
948     case eEncodingT3:
949       Rt = Bits32(opcode, 15, 12);
950       // if BadReg(t) then UNPREDICTABLE;
951       if (BadReg(Rt))
952         return false;
953       registers = (1u << Rt);
954       break;
955     case eEncodingA1:
956       registers = Bits32(opcode, 15, 0);
957       // Instead of return false, let's handle the following case as well,
958       // which amounts to pushing one reg onto the full descending stacks.
959       // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
960       break;
961     case eEncodingA2:
962       Rt = Bits32(opcode, 15, 12);
963       // if t == 13 then UNPREDICTABLE;
964       if (Rt == dwarf_sp)
965         return false;
966       registers = (1u << Rt);
967       break;
968     default:
969       return false;
970     }
971     addr_t sp_offset = addr_byte_size * BitCount(registers);
972     addr_t addr = sp - sp_offset;
973     uint32_t i;
974 
975     EmulateInstruction::Context context;
976     context.type = EmulateInstruction::eContextPushRegisterOnStack;
977     RegisterInfo reg_info;
978     RegisterInfo sp_reg;
979     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
980     for (i = 0; i < 15; ++i) {
981       if (BitIsSet(registers, i)) {
982         GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
983         context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
984         uint32_t reg_value = ReadCoreReg(i, &success);
985         if (!success)
986           return false;
987         if (!MemAWrite(context, addr, reg_value, addr_byte_size))
988           return false;
989         addr += addr_byte_size;
990       }
991     }
992 
993     if (BitIsSet(registers, 15)) {
994       GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
995       context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
996       const uint32_t pc = ReadCoreReg(PC_REG, &success);
997       if (!success)
998         return false;
999       if (!MemAWrite(context, addr, pc, addr_byte_size))
1000         return false;
1001     }
1002 
1003     context.type = EmulateInstruction::eContextAdjustStackPointer;
1004     context.SetImmediateSigned(-sp_offset);
1005 
1006     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1007                                LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1008       return false;
1009   }
1010   return true;
1011 }
1012 
1013 // Pop Multiple Registers loads multiple registers from the stack, loading from
1014 // consecutive memory locations staring at the address in SP, and updates
1015 // SP to point just above the loaded data.
EmulatePOP(const uint32_t opcode,const ARMEncoding encoding)1016 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1017                                        const ARMEncoding encoding) {
1018 #if 0
1019     // ARM pseudo code...
1020     if (ConditionPassed())
1021     {
1022         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1023         address = SP;
1024         for i = 0 to 14
1025             if registers<i> == '1' then
1026                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1027         if registers<15> == '1' then
1028             if UnalignedAllowed then
1029                 LoadWritePC(MemU[address,4]);
1030             else
1031                 LoadWritePC(MemA[address,4]);
1032         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1033         if registers<13> == '1' then SP = bits(32) UNKNOWN;
1034     }
1035 #endif
1036 
1037   bool success = false;
1038 
1039   if (ConditionPassed(opcode)) {
1040     const uint32_t addr_byte_size = GetAddressByteSize();
1041     const addr_t sp = ReadCoreReg(SP_REG, &success);
1042     if (!success)
1043       return false;
1044     uint32_t registers = 0;
1045     uint32_t Rt; // the destination register
1046     switch (encoding) {
1047     case eEncodingT1:
1048       registers = Bits32(opcode, 7, 0);
1049       // The P bit represents PC.
1050       if (Bit32(opcode, 8))
1051         registers |= (1u << 15);
1052       // if BitCount(registers) < 1 then UNPREDICTABLE;
1053       if (BitCount(registers) < 1)
1054         return false;
1055       break;
1056     case eEncodingT2:
1057       // Ignore bit 13.
1058       registers = Bits32(opcode, 15, 0) & ~0x2000;
1059       // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1060       // UNPREDICTABLE;
1061       if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1062         return false;
1063       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1064       // UNPREDICTABLE;
1065       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1066         return false;
1067       break;
1068     case eEncodingT3:
1069       Rt = Bits32(opcode, 15, 12);
1070       // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1071       // UNPREDICTABLE;
1072       if (Rt == 13)
1073         return false;
1074       if (Rt == 15 && InITBlock() && !LastInITBlock())
1075         return false;
1076       registers = (1u << Rt);
1077       break;
1078     case eEncodingA1:
1079       registers = Bits32(opcode, 15, 0);
1080       // Instead of return false, let's handle the following case as well,
1081       // which amounts to popping one reg from the full descending stacks.
1082       // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1083 
1084       // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1085       if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1086         return false;
1087       break;
1088     case eEncodingA2:
1089       Rt = Bits32(opcode, 15, 12);
1090       // if t == 13 then UNPREDICTABLE;
1091       if (Rt == dwarf_sp)
1092         return false;
1093       registers = (1u << Rt);
1094       break;
1095     default:
1096       return false;
1097     }
1098     addr_t sp_offset = addr_byte_size * BitCount(registers);
1099     addr_t addr = sp;
1100     uint32_t i, data;
1101 
1102     EmulateInstruction::Context context;
1103     context.type = EmulateInstruction::eContextPopRegisterOffStack;
1104 
1105     RegisterInfo sp_reg;
1106     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1107 
1108     for (i = 0; i < 15; ++i) {
1109       if (BitIsSet(registers, i)) {
1110         context.SetAddress(addr);
1111         data = MemARead(context, addr, 4, 0, &success);
1112         if (!success)
1113           return false;
1114         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1115                                    data))
1116           return false;
1117         addr += addr_byte_size;
1118       }
1119     }
1120 
1121     if (BitIsSet(registers, 15)) {
1122       context.SetRegisterPlusOffset(sp_reg, addr - sp);
1123       data = MemARead(context, addr, 4, 0, &success);
1124       if (!success)
1125         return false;
1126       // In ARMv5T and above, this is an interworking branch.
1127       if (!LoadWritePC(context, data))
1128         return false;
1129       // addr += addr_byte_size;
1130     }
1131 
1132     context.type = EmulateInstruction::eContextAdjustStackPointer;
1133     context.SetImmediateSigned(sp_offset);
1134 
1135     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1136                                LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1137       return false;
1138   }
1139   return true;
1140 }
1141 
1142 // Set r7 or ip to point to saved value residing within the stack.
1143 // ADD (SP plus immediate)
EmulateADDRdSPImm(const uint32_t opcode,const ARMEncoding encoding)1144 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1145                                               const ARMEncoding encoding) {
1146 #if 0
1147     // ARM pseudo code...
1148     if (ConditionPassed())
1149     {
1150         EncodingSpecificOperations();
1151         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1152         if d == 15 then
1153            ALUWritePC(result); // setflags is always FALSE here
1154         else
1155             R[d] = result;
1156             if setflags then
1157                 APSR.N = result<31>;
1158                 APSR.Z = IsZeroBit(result);
1159                 APSR.C = carry;
1160                 APSR.V = overflow;
1161     }
1162 #endif
1163 
1164   bool success = false;
1165 
1166   if (ConditionPassed(opcode)) {
1167     const addr_t sp = ReadCoreReg(SP_REG, &success);
1168     if (!success)
1169       return false;
1170     uint32_t Rd; // the destination register
1171     uint32_t imm32;
1172     switch (encoding) {
1173     case eEncodingT1:
1174       Rd = 7;
1175       imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1176       break;
1177     case eEncodingA1:
1178       Rd = Bits32(opcode, 15, 12);
1179       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1180       break;
1181     default:
1182       return false;
1183     }
1184     addr_t sp_offset = imm32;
1185     addr_t addr = sp + sp_offset; // a pointer to the stack area
1186 
1187     EmulateInstruction::Context context;
1188     if (Rd == GetFramePointerRegisterNumber())
1189       context.type = eContextSetFramePointer;
1190     else
1191       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1192     RegisterInfo sp_reg;
1193     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1194     context.SetRegisterPlusOffset(sp_reg, sp_offset);
1195 
1196     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1197                                addr))
1198       return false;
1199   }
1200   return true;
1201 }
1202 
1203 // Set r7 or ip to the current stack pointer.
1204 // MOV (register)
EmulateMOVRdSP(const uint32_t opcode,const ARMEncoding encoding)1205 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1206                                            const ARMEncoding encoding) {
1207 #if 0
1208     // ARM pseudo code...
1209     if (ConditionPassed())
1210     {
1211         EncodingSpecificOperations();
1212         result = R[m];
1213         if d == 15 then
1214             ALUWritePC(result); // setflags is always FALSE here
1215         else
1216             R[d] = result;
1217             if setflags then
1218                 APSR.N = result<31>;
1219                 APSR.Z = IsZeroBit(result);
1220                 // APSR.C unchanged
1221                 // APSR.V unchanged
1222     }
1223 #endif
1224 
1225   bool success = false;
1226 
1227   if (ConditionPassed(opcode)) {
1228     const addr_t sp = ReadCoreReg(SP_REG, &success);
1229     if (!success)
1230       return false;
1231     uint32_t Rd; // the destination register
1232     switch (encoding) {
1233     case eEncodingT1:
1234       Rd = 7;
1235       break;
1236     case eEncodingA1:
1237       Rd = 12;
1238       break;
1239     default:
1240       return false;
1241     }
1242 
1243     EmulateInstruction::Context context;
1244     if (Rd == GetFramePointerRegisterNumber())
1245       context.type = EmulateInstruction::eContextSetFramePointer;
1246     else
1247       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1248     RegisterInfo sp_reg;
1249     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1250     context.SetRegisterPlusOffset(sp_reg, 0);
1251 
1252     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1253       return false;
1254   }
1255   return true;
1256 }
1257 
1258 // Move from high register (r8-r15) to low register (r0-r7).
1259 // MOV (register)
EmulateMOVLowHigh(const uint32_t opcode,const ARMEncoding encoding)1260 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1261                                               const ARMEncoding encoding) {
1262   return EmulateMOVRdRm(opcode, encoding);
1263 }
1264 
1265 // Move from register to register.
1266 // MOV (register)
EmulateMOVRdRm(const uint32_t opcode,const ARMEncoding encoding)1267 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1268                                            const ARMEncoding encoding) {
1269 #if 0
1270     // ARM pseudo code...
1271     if (ConditionPassed())
1272     {
1273         EncodingSpecificOperations();
1274         result = R[m];
1275         if d == 15 then
1276             ALUWritePC(result); // setflags is always FALSE here
1277         else
1278             R[d] = result;
1279             if setflags then
1280                 APSR.N = result<31>;
1281                 APSR.Z = IsZeroBit(result);
1282                 // APSR.C unchanged
1283                 // APSR.V unchanged
1284     }
1285 #endif
1286 
1287   bool success = false;
1288 
1289   if (ConditionPassed(opcode)) {
1290     uint32_t Rm; // the source register
1291     uint32_t Rd; // the destination register
1292     bool setflags;
1293     switch (encoding) {
1294     case eEncodingT1:
1295       Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1296       Rm = Bits32(opcode, 6, 3);
1297       setflags = false;
1298       if (Rd == 15 && InITBlock() && !LastInITBlock())
1299         return false;
1300       break;
1301     case eEncodingT2:
1302       Rd = Bits32(opcode, 2, 0);
1303       Rm = Bits32(opcode, 5, 3);
1304       setflags = true;
1305       if (InITBlock())
1306         return false;
1307       break;
1308     case eEncodingT3:
1309       Rd = Bits32(opcode, 11, 8);
1310       Rm = Bits32(opcode, 3, 0);
1311       setflags = BitIsSet(opcode, 20);
1312       // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1313       if (setflags && (BadReg(Rd) || BadReg(Rm)))
1314         return false;
1315       // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1316       // UNPREDICTABLE;
1317       if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1318         return false;
1319       break;
1320     case eEncodingA1:
1321       Rd = Bits32(opcode, 15, 12);
1322       Rm = Bits32(opcode, 3, 0);
1323       setflags = BitIsSet(opcode, 20);
1324 
1325       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1326       // instructions;
1327       if (Rd == 15 && setflags)
1328         return EmulateSUBSPcLrEtc(opcode, encoding);
1329       break;
1330     default:
1331       return false;
1332     }
1333     uint32_t result = ReadCoreReg(Rm, &success);
1334     if (!success)
1335       return false;
1336 
1337     // The context specifies that Rm is to be moved into Rd.
1338     EmulateInstruction::Context context;
1339     if (Rd == 13)
1340       context.type = EmulateInstruction::eContextAdjustStackPointer;
1341     else if (Rd == GetFramePointerRegisterNumber() && Rm == 13)
1342       context.type = EmulateInstruction::eContextSetFramePointer;
1343     else
1344       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1345     RegisterInfo dwarf_reg;
1346     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1347     context.SetRegisterPlusOffset(dwarf_reg, 0);
1348 
1349     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1350       return false;
1351   }
1352   return true;
1353 }
1354 
1355 // Move (immediate) writes an immediate value to the destination register.  It
1356 // can optionally update the condition flags based on the value.
1357 // MOV (immediate)
EmulateMOVRdImm(const uint32_t opcode,const ARMEncoding encoding)1358 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1359                                             const ARMEncoding encoding) {
1360 #if 0
1361     // ARM pseudo code...
1362     if (ConditionPassed())
1363     {
1364         EncodingSpecificOperations();
1365         result = imm32;
1366         if d == 15 then         // Can only occur for ARM encoding
1367             ALUWritePC(result); // setflags is always FALSE here
1368         else
1369             R[d] = result;
1370             if setflags then
1371                 APSR.N = result<31>;
1372                 APSR.Z = IsZeroBit(result);
1373                 APSR.C = carry;
1374                 // APSR.V unchanged
1375     }
1376 #endif
1377 
1378   if (ConditionPassed(opcode)) {
1379     uint32_t Rd;    // the destination register
1380     uint32_t imm32; // the immediate value to be written to Rd
1381     uint32_t carry =
1382         0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1383            // for setflags == false, this value is a don't care initialized to
1384            // 0 to silence the static analyzer
1385     bool setflags;
1386     switch (encoding) {
1387     case eEncodingT1:
1388       Rd = Bits32(opcode, 10, 8);
1389       setflags = !InITBlock();
1390       imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1391       carry = APSR_C;
1392 
1393       break;
1394 
1395     case eEncodingT2:
1396       Rd = Bits32(opcode, 11, 8);
1397       setflags = BitIsSet(opcode, 20);
1398       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1399       if (BadReg(Rd))
1400         return false;
1401 
1402       break;
1403 
1404     case eEncodingT3: {
1405       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1406       // 32);
1407       Rd = Bits32(opcode, 11, 8);
1408       setflags = false;
1409       uint32_t imm4 = Bits32(opcode, 19, 16);
1410       uint32_t imm3 = Bits32(opcode, 14, 12);
1411       uint32_t i = Bit32(opcode, 26);
1412       uint32_t imm8 = Bits32(opcode, 7, 0);
1413       imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1414 
1415       // if BadReg(d) then UNPREDICTABLE;
1416       if (BadReg(Rd))
1417         return false;
1418     } break;
1419 
1420     case eEncodingA1:
1421       // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1422       // ARMExpandImm_C(imm12, APSR.C);
1423       Rd = Bits32(opcode, 15, 12);
1424       setflags = BitIsSet(opcode, 20);
1425       imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1426 
1427       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1428       // instructions;
1429       if ((Rd == 15) && setflags)
1430         return EmulateSUBSPcLrEtc(opcode, encoding);
1431 
1432       break;
1433 
1434     case eEncodingA2: {
1435       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1436       Rd = Bits32(opcode, 15, 12);
1437       setflags = false;
1438       uint32_t imm4 = Bits32(opcode, 19, 16);
1439       uint32_t imm12 = Bits32(opcode, 11, 0);
1440       imm32 = (imm4 << 12) | imm12;
1441 
1442       // if d == 15 then UNPREDICTABLE;
1443       if (Rd == 15)
1444         return false;
1445     } break;
1446 
1447     default:
1448       return false;
1449     }
1450     uint32_t result = imm32;
1451 
1452     // The context specifies that an immediate is to be moved into Rd.
1453     EmulateInstruction::Context context;
1454     context.type = EmulateInstruction::eContextImmediate;
1455     context.SetNoArgs();
1456 
1457     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1458       return false;
1459   }
1460   return true;
1461 }
1462 
1463 // MUL multiplies two register values.  The least significant 32 bits of the
1464 // result are written to the destination
1465 // register.  These 32 bits do not depend on whether the source register values
1466 // are considered to be signed values or unsigned values.
1467 //
1468 // Optionally, it can update the condition flags based on the result.  In the
1469 // Thumb instruction set, this option is limited to only a few forms of the
1470 // instruction.
EmulateMUL(const uint32_t opcode,const ARMEncoding encoding)1471 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1472                                        const ARMEncoding encoding) {
1473 #if 0
1474     if ConditionPassed() then
1475         EncodingSpecificOperations();
1476         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1477         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1478         result = operand1 * operand2;
1479         R[d] = result<31:0>;
1480         if setflags then
1481             APSR.N = result<31>;
1482             APSR.Z = IsZeroBit(result);
1483             if ArchVersion() == 4 then
1484                 APSR.C = bit UNKNOWN;
1485             // else APSR.C unchanged
1486             // APSR.V always unchanged
1487 #endif
1488 
1489   if (ConditionPassed(opcode)) {
1490     uint32_t d;
1491     uint32_t n;
1492     uint32_t m;
1493     bool setflags;
1494 
1495     // EncodingSpecificOperations();
1496     switch (encoding) {
1497     case eEncodingT1:
1498       // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1499       d = Bits32(opcode, 2, 0);
1500       n = Bits32(opcode, 5, 3);
1501       m = Bits32(opcode, 2, 0);
1502       setflags = !InITBlock();
1503 
1504       // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1505       if ((ArchVersion() < ARMv6) && (d == n))
1506         return false;
1507 
1508       break;
1509 
1510     case eEncodingT2:
1511       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1512       d = Bits32(opcode, 11, 8);
1513       n = Bits32(opcode, 19, 16);
1514       m = Bits32(opcode, 3, 0);
1515       setflags = false;
1516 
1517       // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1518       if (BadReg(d) || BadReg(n) || BadReg(m))
1519         return false;
1520 
1521       break;
1522 
1523     case eEncodingA1:
1524       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1525       d = Bits32(opcode, 19, 16);
1526       n = Bits32(opcode, 3, 0);
1527       m = Bits32(opcode, 11, 8);
1528       setflags = BitIsSet(opcode, 20);
1529 
1530       // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1531       if ((d == 15) || (n == 15) || (m == 15))
1532         return false;
1533 
1534       // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1535       if ((ArchVersion() < ARMv6) && (d == n))
1536         return false;
1537 
1538       break;
1539 
1540     default:
1541       return false;
1542     }
1543 
1544     bool success = false;
1545 
1546     // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1547     // results
1548     uint64_t operand1 =
1549         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1550     if (!success)
1551       return false;
1552 
1553     // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1554     // results
1555     uint64_t operand2 =
1556         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1557     if (!success)
1558       return false;
1559 
1560     // result = operand1 * operand2;
1561     uint64_t result = operand1 * operand2;
1562 
1563     // R[d] = result<31:0>;
1564     RegisterInfo op1_reg;
1565     RegisterInfo op2_reg;
1566     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1567     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1568 
1569     EmulateInstruction::Context context;
1570     context.type = eContextArithmetic;
1571     context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1572 
1573     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1574                                (0x0000ffff & result)))
1575       return false;
1576 
1577     // if setflags then
1578     if (setflags) {
1579       // APSR.N = result<31>;
1580       // APSR.Z = IsZeroBit(result);
1581       m_new_inst_cpsr = m_opcode_cpsr;
1582       SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1583       SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1584       if (m_new_inst_cpsr != m_opcode_cpsr) {
1585         if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1586                                    LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1587           return false;
1588       }
1589 
1590       // if ArchVersion() == 4 then
1591       // APSR.C = bit UNKNOWN;
1592     }
1593   }
1594   return true;
1595 }
1596 
1597 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1598 // the destination register. It can optionally update the condition flags based
1599 // on the value.
EmulateMVNImm(const uint32_t opcode,const ARMEncoding encoding)1600 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1601                                           const ARMEncoding encoding) {
1602 #if 0
1603     // ARM pseudo code...
1604     if (ConditionPassed())
1605     {
1606         EncodingSpecificOperations();
1607         result = NOT(imm32);
1608         if d == 15 then         // Can only occur for ARM encoding
1609             ALUWritePC(result); // setflags is always FALSE here
1610         else
1611             R[d] = result;
1612             if setflags then
1613                 APSR.N = result<31>;
1614                 APSR.Z = IsZeroBit(result);
1615                 APSR.C = carry;
1616                 // APSR.V unchanged
1617     }
1618 #endif
1619 
1620   if (ConditionPassed(opcode)) {
1621     uint32_t Rd;    // the destination register
1622     uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1623     uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1624     bool setflags;
1625     switch (encoding) {
1626     case eEncodingT1:
1627       Rd = Bits32(opcode, 11, 8);
1628       setflags = BitIsSet(opcode, 20);
1629       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1630       break;
1631     case eEncodingA1:
1632       Rd = Bits32(opcode, 15, 12);
1633       setflags = BitIsSet(opcode, 20);
1634       imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1635 
1636       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1637       // instructions;
1638       if (Rd == 15 && setflags)
1639         return EmulateSUBSPcLrEtc(opcode, encoding);
1640       break;
1641     default:
1642       return false;
1643     }
1644     uint32_t result = ~imm32;
1645 
1646     // The context specifies that an immediate is to be moved into Rd.
1647     EmulateInstruction::Context context;
1648     context.type = EmulateInstruction::eContextImmediate;
1649     context.SetNoArgs();
1650 
1651     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1652       return false;
1653   }
1654   return true;
1655 }
1656 
1657 // Bitwise NOT (register) writes the bitwise inverse of a register value to the
1658 // destination register. It can optionally update the condition flags based on
1659 // the result.
EmulateMVNReg(const uint32_t opcode,const ARMEncoding encoding)1660 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1661                                           const ARMEncoding encoding) {
1662 #if 0
1663     // ARM pseudo code...
1664     if (ConditionPassed())
1665     {
1666         EncodingSpecificOperations();
1667         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1668         result = NOT(shifted);
1669         if d == 15 then         // Can only occur for ARM encoding
1670             ALUWritePC(result); // setflags is always FALSE here
1671         else
1672             R[d] = result;
1673             if setflags then
1674                 APSR.N = result<31>;
1675                 APSR.Z = IsZeroBit(result);
1676                 APSR.C = carry;
1677                 // APSR.V unchanged
1678     }
1679 #endif
1680 
1681   if (ConditionPassed(opcode)) {
1682     uint32_t Rm; // the source register
1683     uint32_t Rd; // the destination register
1684     ARM_ShifterType shift_t;
1685     uint32_t shift_n; // the shift applied to the value read from Rm
1686     bool setflags;
1687     uint32_t carry; // the carry bit after the shift operation
1688     switch (encoding) {
1689     case eEncodingT1:
1690       Rd = Bits32(opcode, 2, 0);
1691       Rm = Bits32(opcode, 5, 3);
1692       setflags = !InITBlock();
1693       shift_t = SRType_LSL;
1694       shift_n = 0;
1695       if (InITBlock())
1696         return false;
1697       break;
1698     case eEncodingT2:
1699       Rd = Bits32(opcode, 11, 8);
1700       Rm = Bits32(opcode, 3, 0);
1701       setflags = BitIsSet(opcode, 20);
1702       shift_n = DecodeImmShiftThumb(opcode, shift_t);
1703       // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1704       if (BadReg(Rd) || BadReg(Rm))
1705         return false;
1706       break;
1707     case eEncodingA1:
1708       Rd = Bits32(opcode, 15, 12);
1709       Rm = Bits32(opcode, 3, 0);
1710       setflags = BitIsSet(opcode, 20);
1711       shift_n = DecodeImmShiftARM(opcode, shift_t);
1712       break;
1713     default:
1714       return false;
1715     }
1716     bool success = false;
1717     uint32_t value = ReadCoreReg(Rm, &success);
1718     if (!success)
1719       return false;
1720 
1721     uint32_t shifted =
1722         Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1723     if (!success)
1724       return false;
1725     uint32_t result = ~shifted;
1726 
1727     // The context specifies that an immediate is to be moved into Rd.
1728     EmulateInstruction::Context context;
1729     context.type = EmulateInstruction::eContextImmediate;
1730     context.SetNoArgs();
1731 
1732     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1733       return false;
1734   }
1735   return true;
1736 }
1737 
1738 // PC relative immediate load into register, possibly followed by ADD (SP plus
1739 // register).
1740 // LDR (literal)
EmulateLDRRtPCRelative(const uint32_t opcode,const ARMEncoding encoding)1741 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1742                                                    const ARMEncoding encoding) {
1743 #if 0
1744     // ARM pseudo code...
1745     if (ConditionPassed())
1746     {
1747         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1748         base = Align(PC,4);
1749         address = if add then (base + imm32) else (base - imm32);
1750         data = MemU[address,4];
1751         if t == 15 then
1752             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1753         elsif UnalignedSupport() || address<1:0> = '00' then
1754             R[t] = data;
1755         else // Can only apply before ARMv7
1756             if CurrentInstrSet() == InstrSet_ARM then
1757                 R[t] = ROR(data, 8*UInt(address<1:0>));
1758             else
1759                 R[t] = bits(32) UNKNOWN;
1760     }
1761 #endif
1762 
1763   if (ConditionPassed(opcode)) {
1764     bool success = false;
1765     const uint32_t pc = ReadCoreReg(PC_REG, &success);
1766     if (!success)
1767       return false;
1768 
1769     // PC relative immediate load context
1770     EmulateInstruction::Context context;
1771     context.type = EmulateInstruction::eContextRegisterPlusOffset;
1772     RegisterInfo pc_reg;
1773     GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1774     context.SetRegisterPlusOffset(pc_reg, 0);
1775 
1776     uint32_t Rt;    // the destination register
1777     uint32_t imm32; // immediate offset from the PC
1778     bool add;       // +imm32 or -imm32?
1779     addr_t base;    // the base address
1780     addr_t address; // the PC relative address
1781     uint32_t data;  // the literal data value from the PC relative load
1782     switch (encoding) {
1783     case eEncodingT1:
1784       Rt = Bits32(opcode, 10, 8);
1785       imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1786       add = true;
1787       break;
1788     case eEncodingT2:
1789       Rt = Bits32(opcode, 15, 12);
1790       imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1791       add = BitIsSet(opcode, 23);
1792       if (Rt == 15 && InITBlock() && !LastInITBlock())
1793         return false;
1794       break;
1795     default:
1796       return false;
1797     }
1798 
1799     base = Align(pc, 4);
1800     if (add)
1801       address = base + imm32;
1802     else
1803       address = base - imm32;
1804 
1805     context.SetRegisterPlusOffset(pc_reg, address - base);
1806     data = MemURead(context, address, 4, 0, &success);
1807     if (!success)
1808       return false;
1809 
1810     if (Rt == 15) {
1811       if (Bits32(address, 1, 0) == 0) {
1812         // In ARMv5T and above, this is an interworking branch.
1813         if (!LoadWritePC(context, data))
1814           return false;
1815       } else
1816         return false;
1817     } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1818       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1819                                  data))
1820         return false;
1821     } else // We don't handle ARM for now.
1822       return false;
1823   }
1824   return true;
1825 }
1826 
1827 // An add operation to adjust the SP.
1828 // ADD (SP plus immediate)
EmulateADDSPImm(const uint32_t opcode,const ARMEncoding encoding)1829 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1830                                             const ARMEncoding encoding) {
1831 #if 0
1832     // ARM pseudo code...
1833     if (ConditionPassed())
1834     {
1835         EncodingSpecificOperations();
1836         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1837         if d == 15 then // Can only occur for ARM encoding
1838             ALUWritePC(result); // setflags is always FALSE here
1839         else
1840             R[d] = result;
1841             if setflags then
1842                 APSR.N = result<31>;
1843                 APSR.Z = IsZeroBit(result);
1844                 APSR.C = carry;
1845                 APSR.V = overflow;
1846     }
1847 #endif
1848 
1849   bool success = false;
1850 
1851   if (ConditionPassed(opcode)) {
1852     const addr_t sp = ReadCoreReg(SP_REG, &success);
1853     if (!success)
1854       return false;
1855     uint32_t imm32; // the immediate operand
1856     uint32_t d;
1857     bool setflags;
1858     switch (encoding) {
1859     case eEncodingT1:
1860       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1861       d = Bits32(opcode, 10, 8);
1862       imm32 = (Bits32(opcode, 7, 0) << 2);
1863       setflags = false;
1864       break;
1865 
1866     case eEncodingT2:
1867       // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1868       d = 13;
1869       imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1870       setflags = false;
1871       break;
1872 
1873     case eEncodingT3:
1874       // d = UInt(Rd); setflags = (S == "1"); imm32 =
1875       // ThumbExpandImm(i:imm3:imm8);
1876       d = Bits32(opcode, 11, 8);
1877       imm32 = ThumbExpandImm(opcode);
1878       setflags = Bit32(opcode, 20);
1879 
1880       // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1881       if (d == 15 && setflags == 1)
1882         return false; // CMN (immediate) not yet supported
1883 
1884       // if d == 15 && S == "0" then UNPREDICTABLE;
1885       if (d == 15 && setflags == 0)
1886         return false;
1887       break;
1888 
1889     case eEncodingT4: {
1890       // if Rn == '1111' then SEE ADR;
1891       // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1892       d = Bits32(opcode, 11, 8);
1893       setflags = false;
1894       uint32_t i = Bit32(opcode, 26);
1895       uint32_t imm3 = Bits32(opcode, 14, 12);
1896       uint32_t imm8 = Bits32(opcode, 7, 0);
1897       imm32 = (i << 11) | (imm3 << 8) | imm8;
1898 
1899       // if d == 15 then UNPREDICTABLE;
1900       if (d == 15)
1901         return false;
1902     } break;
1903 
1904     default:
1905       return false;
1906     }
1907     // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1908     AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1909 
1910     EmulateInstruction::Context context;
1911     if (d == 13)
1912       context.type = EmulateInstruction::eContextAdjustStackPointer;
1913     else
1914       context.type = EmulateInstruction::eContextRegisterPlusOffset;
1915 
1916     RegisterInfo sp_reg;
1917     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1918     context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1919 
1920     if (d == 15) {
1921       if (!ALUWritePC(context, res.result))
1922         return false;
1923     } else {
1924       // R[d] = result;
1925       // if setflags then
1926       //     APSR.N = result<31>;
1927       //     APSR.Z = IsZeroBit(result);
1928       //     APSR.C = carry;
1929       //     APSR.V = overflow;
1930       if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1931                                      res.carry_out, res.overflow))
1932         return false;
1933     }
1934   }
1935   return true;
1936 }
1937 
1938 // An add operation to adjust the SP.
1939 // ADD (SP plus register)
EmulateADDSPRm(const uint32_t opcode,const ARMEncoding encoding)1940 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1941                                            const ARMEncoding encoding) {
1942 #if 0
1943     // ARM pseudo code...
1944     if (ConditionPassed())
1945     {
1946         EncodingSpecificOperations();
1947         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1948         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1949         if d == 15 then
1950             ALUWritePC(result); // setflags is always FALSE here
1951         else
1952             R[d] = result;
1953             if setflags then
1954                 APSR.N = result<31>;
1955                 APSR.Z = IsZeroBit(result);
1956                 APSR.C = carry;
1957                 APSR.V = overflow;
1958     }
1959 #endif
1960 
1961   bool success = false;
1962 
1963   if (ConditionPassed(opcode)) {
1964     const addr_t sp = ReadCoreReg(SP_REG, &success);
1965     if (!success)
1966       return false;
1967     uint32_t Rm; // the second operand
1968     switch (encoding) {
1969     case eEncodingT2:
1970       Rm = Bits32(opcode, 6, 3);
1971       break;
1972     default:
1973       return false;
1974     }
1975     int32_t reg_value = ReadCoreReg(Rm, &success);
1976     if (!success)
1977       return false;
1978 
1979     addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1980 
1981     EmulateInstruction::Context context;
1982     context.type = eContextArithmetic;
1983     RegisterInfo sp_reg;
1984     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1985 
1986     RegisterInfo other_reg;
1987     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1988     context.SetRegisterRegisterOperands(sp_reg, other_reg);
1989 
1990     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1991                                LLDB_REGNUM_GENERIC_SP, addr))
1992       return false;
1993   }
1994   return true;
1995 }
1996 
1997 // Branch with Link and Exchange Instruction Sets (immediate) calls a
1998 // subroutine at a PC-relative address, and changes instruction set from ARM to
1999 // Thumb, or from Thumb to ARM.
2000 // BLX (immediate)
EmulateBLXImmediate(const uint32_t opcode,const ARMEncoding encoding)2001 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2002                                                 const ARMEncoding encoding) {
2003 #if 0
2004     // ARM pseudo code...
2005     if (ConditionPassed())
2006     {
2007         EncodingSpecificOperations();
2008         if CurrentInstrSet() == InstrSet_ARM then
2009             LR = PC - 4;
2010         else
2011             LR = PC<31:1> : '1';
2012         if targetInstrSet == InstrSet_ARM then
2013             targetAddress = Align(PC,4) + imm32;
2014         else
2015             targetAddress = PC + imm32;
2016         SelectInstrSet(targetInstrSet);
2017         BranchWritePC(targetAddress);
2018     }
2019 #endif
2020 
2021   bool success = true;
2022 
2023   if (ConditionPassed(opcode)) {
2024     EmulateInstruction::Context context;
2025     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2026     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2027     if (!success)
2028       return false;
2029     addr_t lr;     // next instruction address
2030     addr_t target; // target address
2031     int32_t imm32; // PC-relative offset
2032     switch (encoding) {
2033     case eEncodingT1: {
2034       lr = pc | 1u; // return address
2035       uint32_t S = Bit32(opcode, 26);
2036       uint32_t imm10 = Bits32(opcode, 25, 16);
2037       uint32_t J1 = Bit32(opcode, 13);
2038       uint32_t J2 = Bit32(opcode, 11);
2039       uint32_t imm11 = Bits32(opcode, 10, 0);
2040       uint32_t I1 = !(J1 ^ S);
2041       uint32_t I2 = !(J2 ^ S);
2042       uint32_t imm25 =
2043           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2044       imm32 = llvm::SignExtend32<25>(imm25);
2045       target = pc + imm32;
2046       SelectInstrSet(eModeThumb);
2047       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2048       if (InITBlock() && !LastInITBlock())
2049         return false;
2050       break;
2051     }
2052     case eEncodingT2: {
2053       lr = pc | 1u; // return address
2054       uint32_t S = Bit32(opcode, 26);
2055       uint32_t imm10H = Bits32(opcode, 25, 16);
2056       uint32_t J1 = Bit32(opcode, 13);
2057       uint32_t J2 = Bit32(opcode, 11);
2058       uint32_t imm10L = Bits32(opcode, 10, 1);
2059       uint32_t I1 = !(J1 ^ S);
2060       uint32_t I2 = !(J2 ^ S);
2061       uint32_t imm25 =
2062           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2063       imm32 = llvm::SignExtend32<25>(imm25);
2064       target = Align(pc, 4) + imm32;
2065       SelectInstrSet(eModeARM);
2066       context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2067       if (InITBlock() && !LastInITBlock())
2068         return false;
2069       break;
2070     }
2071     case eEncodingA1:
2072       lr = pc - 4; // return address
2073       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2074       target = Align(pc, 4) + imm32;
2075       SelectInstrSet(eModeARM);
2076       context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2077       break;
2078     case eEncodingA2:
2079       lr = pc - 4; // return address
2080       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2081                                      Bits32(opcode, 24, 24) << 1);
2082       target = pc + imm32;
2083       SelectInstrSet(eModeThumb);
2084       context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2085       break;
2086     default:
2087       return false;
2088     }
2089     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2090                                LLDB_REGNUM_GENERIC_RA, lr))
2091       return false;
2092     if (!BranchWritePC(context, target))
2093       return false;
2094     if (m_opcode_cpsr != m_new_inst_cpsr)
2095       if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2096                                  LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2097         return false;
2098   }
2099   return true;
2100 }
2101 
2102 // Branch with Link and Exchange (register) calls a subroutine at an address
2103 // and instruction set specified by a register.
2104 // BLX (register)
EmulateBLXRm(const uint32_t opcode,const ARMEncoding encoding)2105 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2106                                          const ARMEncoding encoding) {
2107 #if 0
2108     // ARM pseudo code...
2109     if (ConditionPassed())
2110     {
2111         EncodingSpecificOperations();
2112         target = R[m];
2113         if CurrentInstrSet() == InstrSet_ARM then
2114             next_instr_addr = PC - 4;
2115             LR = next_instr_addr;
2116         else
2117             next_instr_addr = PC - 2;
2118             LR = next_instr_addr<31:1> : '1';
2119         BXWritePC(target);
2120     }
2121 #endif
2122 
2123   bool success = false;
2124 
2125   if (ConditionPassed(opcode)) {
2126     EmulateInstruction::Context context;
2127     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2128     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2129     addr_t lr; // next instruction address
2130     if (!success)
2131       return false;
2132     uint32_t Rm; // the register with the target address
2133     switch (encoding) {
2134     case eEncodingT1:
2135       lr = (pc - 2) | 1u; // return address
2136       Rm = Bits32(opcode, 6, 3);
2137       // if m == 15 then UNPREDICTABLE;
2138       if (Rm == 15)
2139         return false;
2140       if (InITBlock() && !LastInITBlock())
2141         return false;
2142       break;
2143     case eEncodingA1:
2144       lr = pc - 4; // return address
2145       Rm = Bits32(opcode, 3, 0);
2146       // if m == 15 then UNPREDICTABLE;
2147       if (Rm == 15)
2148         return false;
2149       break;
2150     default:
2151       return false;
2152     }
2153     addr_t target = ReadCoreReg(Rm, &success);
2154     if (!success)
2155       return false;
2156     RegisterInfo dwarf_reg;
2157     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2158     context.SetRegister(dwarf_reg);
2159     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2160                                LLDB_REGNUM_GENERIC_RA, lr))
2161       return false;
2162     if (!BXWritePC(context, target))
2163       return false;
2164   }
2165   return true;
2166 }
2167 
2168 // Branch and Exchange causes a branch to an address and instruction set
2169 // specified by a register.
EmulateBXRm(const uint32_t opcode,const ARMEncoding encoding)2170 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2171                                         const ARMEncoding encoding) {
2172 #if 0
2173     // ARM pseudo code...
2174     if (ConditionPassed())
2175     {
2176         EncodingSpecificOperations();
2177         BXWritePC(R[m]);
2178     }
2179 #endif
2180 
2181   if (ConditionPassed(opcode)) {
2182     EmulateInstruction::Context context;
2183     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2184     uint32_t Rm; // the register with the target address
2185     switch (encoding) {
2186     case eEncodingT1:
2187       Rm = Bits32(opcode, 6, 3);
2188       if (InITBlock() && !LastInITBlock())
2189         return false;
2190       break;
2191     case eEncodingA1:
2192       Rm = Bits32(opcode, 3, 0);
2193       break;
2194     default:
2195       return false;
2196     }
2197     bool success = false;
2198     addr_t target = ReadCoreReg(Rm, &success);
2199     if (!success)
2200       return false;
2201 
2202     RegisterInfo dwarf_reg;
2203     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2204     context.SetRegister(dwarf_reg);
2205     if (!BXWritePC(context, target))
2206       return false;
2207   }
2208   return true;
2209 }
2210 
2211 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2212 // attempt fails, it branches to an address and instruction set specified by a
2213 // register as though it were a BX instruction.
2214 //
2215 // TODO: Emulate Jazelle architecture?
2216 //       We currently assume that switching to Jazelle state fails, thus
2217 //       treating BXJ as a BX operation.
EmulateBXJRm(const uint32_t opcode,const ARMEncoding encoding)2218 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2219                                          const ARMEncoding encoding) {
2220 #if 0
2221     // ARM pseudo code...
2222     if (ConditionPassed())
2223     {
2224         EncodingSpecificOperations();
2225         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2226             BXWritePC(R[m]);
2227         else
2228             if JazelleAcceptsExecution() then
2229                 SwitchToJazelleExecution();
2230             else
2231                 SUBARCHITECTURE_DEFINED handler call;
2232     }
2233 #endif
2234 
2235   if (ConditionPassed(opcode)) {
2236     EmulateInstruction::Context context;
2237     context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2238     uint32_t Rm; // the register with the target address
2239     switch (encoding) {
2240     case eEncodingT1:
2241       Rm = Bits32(opcode, 19, 16);
2242       if (BadReg(Rm))
2243         return false;
2244       if (InITBlock() && !LastInITBlock())
2245         return false;
2246       break;
2247     case eEncodingA1:
2248       Rm = Bits32(opcode, 3, 0);
2249       if (Rm == 15)
2250         return false;
2251       break;
2252     default:
2253       return false;
2254     }
2255     bool success = false;
2256     addr_t target = ReadCoreReg(Rm, &success);
2257     if (!success)
2258       return false;
2259 
2260     RegisterInfo dwarf_reg;
2261     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2262     context.SetRegister(dwarf_reg);
2263     if (!BXWritePC(context, target))
2264       return false;
2265   }
2266   return true;
2267 }
2268 
2269 // Set r7 to point to some ip offset.
2270 // SUB (immediate)
EmulateSUBR7IPImm(const uint32_t opcode,const ARMEncoding encoding)2271 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2272                                               const ARMEncoding encoding) {
2273 #if 0
2274     // ARM pseudo code...
2275     if (ConditionPassed())
2276     {
2277         EncodingSpecificOperations();
2278         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2279         if d == 15 then // Can only occur for ARM encoding
2280            ALUWritePC(result); // setflags is always FALSE here
2281         else
2282             R[d] = result;
2283             if setflags then
2284                 APSR.N = result<31>;
2285                 APSR.Z = IsZeroBit(result);
2286                 APSR.C = carry;
2287                 APSR.V = overflow;
2288     }
2289 #endif
2290 
2291   if (ConditionPassed(opcode)) {
2292     bool success = false;
2293     const addr_t ip = ReadCoreReg(12, &success);
2294     if (!success)
2295       return false;
2296     uint32_t imm32;
2297     switch (encoding) {
2298     case eEncodingA1:
2299       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2300       break;
2301     default:
2302       return false;
2303     }
2304     addr_t ip_offset = imm32;
2305     addr_t addr = ip - ip_offset; // the adjusted ip value
2306 
2307     EmulateInstruction::Context context;
2308     context.type = EmulateInstruction::eContextRegisterPlusOffset;
2309     RegisterInfo dwarf_reg;
2310     GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2311     context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2312 
2313     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2314       return false;
2315   }
2316   return true;
2317 }
2318 
2319 // Set ip to point to some stack offset.
2320 // SUB (SP minus immediate)
EmulateSUBIPSPImm(const uint32_t opcode,const ARMEncoding encoding)2321 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2322                                               const ARMEncoding encoding) {
2323 #if 0
2324     // ARM pseudo code...
2325     if (ConditionPassed())
2326     {
2327         EncodingSpecificOperations();
2328         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2329         if d == 15 then // Can only occur for ARM encoding
2330            ALUWritePC(result); // setflags is always FALSE here
2331         else
2332             R[d] = result;
2333             if setflags then
2334                 APSR.N = result<31>;
2335                 APSR.Z = IsZeroBit(result);
2336                 APSR.C = carry;
2337                 APSR.V = overflow;
2338     }
2339 #endif
2340 
2341   if (ConditionPassed(opcode)) {
2342     bool success = false;
2343     const addr_t sp = ReadCoreReg(SP_REG, &success);
2344     if (!success)
2345       return false;
2346     uint32_t imm32;
2347     switch (encoding) {
2348     case eEncodingA1:
2349       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2350       break;
2351     default:
2352       return false;
2353     }
2354     addr_t sp_offset = imm32;
2355     addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2356 
2357     EmulateInstruction::Context context;
2358     context.type = EmulateInstruction::eContextRegisterPlusOffset;
2359     RegisterInfo dwarf_reg;
2360     GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2361     context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2362 
2363     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2364       return false;
2365   }
2366   return true;
2367 }
2368 
2369 // This instruction subtracts an immediate value from the SP value, and writes
2370 // the result to the destination register.
2371 //
2372 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2373 // storage.
EmulateSUBSPImm(const uint32_t opcode,const ARMEncoding encoding)2374 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2375                                             const ARMEncoding encoding) {
2376 #if 0
2377     // ARM pseudo code...
2378     if (ConditionPassed())
2379     {
2380         EncodingSpecificOperations();
2381         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2382         if d == 15 then        // Can only occur for ARM encoding
2383            ALUWritePC(result); // setflags is always FALSE here
2384         else
2385             R[d] = result;
2386             if setflags then
2387                 APSR.N = result<31>;
2388                 APSR.Z = IsZeroBit(result);
2389                 APSR.C = carry;
2390                 APSR.V = overflow;
2391     }
2392 #endif
2393 
2394   bool success = false;
2395   if (ConditionPassed(opcode)) {
2396     const addr_t sp = ReadCoreReg(SP_REG, &success);
2397     if (!success)
2398       return false;
2399 
2400     uint32_t Rd;
2401     bool setflags;
2402     uint32_t imm32;
2403     switch (encoding) {
2404     case eEncodingT1:
2405       Rd = 13;
2406       setflags = false;
2407       imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2408       break;
2409     case eEncodingT2:
2410       Rd = Bits32(opcode, 11, 8);
2411       setflags = BitIsSet(opcode, 20);
2412       imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2413       if (Rd == 15 && setflags)
2414         return EmulateCMPImm(opcode, eEncodingT2);
2415       if (Rd == 15 && !setflags)
2416         return false;
2417       break;
2418     case eEncodingT3:
2419       Rd = Bits32(opcode, 11, 8);
2420       setflags = false;
2421       imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2422       if (Rd == 15)
2423         return false;
2424       break;
2425     case eEncodingA1:
2426       Rd = Bits32(opcode, 15, 12);
2427       setflags = BitIsSet(opcode, 20);
2428       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2429 
2430       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2431       // instructions;
2432       if (Rd == 15 && setflags)
2433         return EmulateSUBSPcLrEtc(opcode, encoding);
2434       break;
2435     default:
2436       return false;
2437     }
2438     AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2439 
2440     EmulateInstruction::Context context;
2441     if (Rd == 13) {
2442       uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2443                               // to negate it, or the wrong
2444       // value gets passed down to context.SetImmediateSigned.
2445       context.type = EmulateInstruction::eContextAdjustStackPointer;
2446       context.SetImmediateSigned(-imm64); // the stack pointer offset
2447     } else {
2448       context.type = EmulateInstruction::eContextImmediate;
2449       context.SetNoArgs();
2450     }
2451 
2452     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2453                                    res.carry_out, res.overflow))
2454       return false;
2455   }
2456   return true;
2457 }
2458 
2459 // A store operation to the stack that also updates the SP.
EmulateSTRRtSP(const uint32_t opcode,const ARMEncoding encoding)2460 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2461                                            const ARMEncoding encoding) {
2462 #if 0
2463     // ARM pseudo code...
2464     if (ConditionPassed())
2465     {
2466         EncodingSpecificOperations();
2467         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2468         address = if index then offset_addr else R[n];
2469         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2470         if wback then R[n] = offset_addr;
2471     }
2472 #endif
2473 
2474   bool success = false;
2475   if (ConditionPassed(opcode)) {
2476     const uint32_t addr_byte_size = GetAddressByteSize();
2477     const addr_t sp = ReadCoreReg(SP_REG, &success);
2478     if (!success)
2479       return false;
2480     uint32_t Rt; // the source register
2481     uint32_t imm12;
2482     uint32_t
2483         Rn; // This function assumes Rn is the SP, but we should verify that.
2484 
2485     bool index;
2486     bool add;
2487     bool wback;
2488     switch (encoding) {
2489     case eEncodingA1:
2490       Rt = Bits32(opcode, 15, 12);
2491       imm12 = Bits32(opcode, 11, 0);
2492       Rn = Bits32(opcode, 19, 16);
2493 
2494       if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2495         return false;
2496 
2497       index = BitIsSet(opcode, 24);
2498       add = BitIsSet(opcode, 23);
2499       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2500 
2501       if (wback && ((Rn == 15) || (Rn == Rt)))
2502         return false;
2503       break;
2504     default:
2505       return false;
2506     }
2507     addr_t offset_addr;
2508     if (add)
2509       offset_addr = sp + imm12;
2510     else
2511       offset_addr = sp - imm12;
2512 
2513     addr_t addr;
2514     if (index)
2515       addr = offset_addr;
2516     else
2517       addr = sp;
2518 
2519     EmulateInstruction::Context context;
2520     context.type = EmulateInstruction::eContextPushRegisterOnStack;
2521     RegisterInfo sp_reg;
2522     RegisterInfo dwarf_reg;
2523 
2524     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2525     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2526     context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2527     if (Rt != 15) {
2528       uint32_t reg_value = ReadCoreReg(Rt, &success);
2529       if (!success)
2530         return false;
2531       if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2532         return false;
2533     } else {
2534       const uint32_t pc = ReadCoreReg(PC_REG, &success);
2535       if (!success)
2536         return false;
2537       if (!MemUWrite(context, addr, pc, addr_byte_size))
2538         return false;
2539     }
2540 
2541     if (wback) {
2542       context.type = EmulateInstruction::eContextAdjustStackPointer;
2543       context.SetImmediateSigned(addr - sp);
2544       if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2545                                  LLDB_REGNUM_GENERIC_SP, offset_addr))
2546         return false;
2547     }
2548   }
2549   return true;
2550 }
2551 
2552 // Vector Push stores multiple extension registers to the stack. It also
2553 // updates SP to point to the start of the stored data.
EmulateVPUSH(const uint32_t opcode,const ARMEncoding encoding)2554 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2555                                          const ARMEncoding encoding) {
2556 #if 0
2557     // ARM pseudo code...
2558     if (ConditionPassed())
2559     {
2560         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2561         address = SP - imm32;
2562         SP = SP - imm32;
2563         if single_regs then
2564             for r = 0 to regs-1
2565                 MemA[address,4] = S[d+r]; address = address+4;
2566         else
2567             for r = 0 to regs-1
2568                 // Store as two word-aligned words in the correct order for
2569                 // current endianness.
2570                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2571                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2572                 address = address+8;
2573     }
2574 #endif
2575 
2576   bool success = false;
2577   if (ConditionPassed(opcode)) {
2578     const uint32_t addr_byte_size = GetAddressByteSize();
2579     const addr_t sp = ReadCoreReg(SP_REG, &success);
2580     if (!success)
2581       return false;
2582     bool single_regs;
2583     uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2584     uint32_t imm32; // stack offset
2585     uint32_t regs;  // number of registers
2586     switch (encoding) {
2587     case eEncodingT1:
2588     case eEncodingA1:
2589       single_regs = false;
2590       d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2591       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2592       // If UInt(imm8) is odd, see "FSTMX".
2593       regs = Bits32(opcode, 7, 0) / 2;
2594       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2595       if (regs == 0 || regs > 16 || (d + regs) > 32)
2596         return false;
2597       break;
2598     case eEncodingT2:
2599     case eEncodingA2:
2600       single_regs = true;
2601       d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2602       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2603       regs = Bits32(opcode, 7, 0);
2604       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2605       if (regs == 0 || regs > 16 || (d + regs) > 32)
2606         return false;
2607       break;
2608     default:
2609       return false;
2610     }
2611     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2612     uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2613     addr_t sp_offset = imm32;
2614     addr_t addr = sp - sp_offset;
2615     uint32_t i;
2616 
2617     EmulateInstruction::Context context;
2618     context.type = EmulateInstruction::eContextPushRegisterOnStack;
2619 
2620     RegisterInfo dwarf_reg;
2621     RegisterInfo sp_reg;
2622     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2623     for (i = 0; i < regs; ++i) {
2624       GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2625       context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2626       // uint64_t to accommodate 64-bit registers.
2627       uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2628       if (!success)
2629         return false;
2630       if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2631         return false;
2632       addr += reg_byte_size;
2633     }
2634 
2635     context.type = EmulateInstruction::eContextAdjustStackPointer;
2636     context.SetImmediateSigned(-sp_offset);
2637 
2638     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2639                                LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2640       return false;
2641   }
2642   return true;
2643 }
2644 
2645 // Vector Pop loads multiple extension registers from the stack. It also
2646 // updates SP to point just above the loaded data.
EmulateVPOP(const uint32_t opcode,const ARMEncoding encoding)2647 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2648                                         const ARMEncoding encoding) {
2649 #if 0
2650     // ARM pseudo code...
2651     if (ConditionPassed())
2652     {
2653         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2654         address = SP;
2655         SP = SP + imm32;
2656         if single_regs then
2657             for r = 0 to regs-1
2658                 S[d+r] = MemA[address,4]; address = address+4;
2659         else
2660             for r = 0 to regs-1
2661                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2662                 // Combine the word-aligned words in the correct order for
2663                 // current endianness.
2664                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2665     }
2666 #endif
2667 
2668   bool success = false;
2669   if (ConditionPassed(opcode)) {
2670     const uint32_t addr_byte_size = GetAddressByteSize();
2671     const addr_t sp = ReadCoreReg(SP_REG, &success);
2672     if (!success)
2673       return false;
2674     bool single_regs;
2675     uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2676     uint32_t imm32; // stack offset
2677     uint32_t regs;  // number of registers
2678     switch (encoding) {
2679     case eEncodingT1:
2680     case eEncodingA1:
2681       single_regs = false;
2682       d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2683       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2684       // If UInt(imm8) is odd, see "FLDMX".
2685       regs = Bits32(opcode, 7, 0) / 2;
2686       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2687       if (regs == 0 || regs > 16 || (d + regs) > 32)
2688         return false;
2689       break;
2690     case eEncodingT2:
2691     case eEncodingA2:
2692       single_regs = true;
2693       d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2694       imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2695       regs = Bits32(opcode, 7, 0);
2696       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2697       if (regs == 0 || regs > 16 || (d + regs) > 32)
2698         return false;
2699       break;
2700     default:
2701       return false;
2702     }
2703     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2704     uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2705     addr_t sp_offset = imm32;
2706     addr_t addr = sp;
2707     uint32_t i;
2708     uint64_t data; // uint64_t to accommodate 64-bit registers.
2709 
2710     EmulateInstruction::Context context;
2711     context.type = EmulateInstruction::eContextPopRegisterOffStack;
2712 
2713     RegisterInfo dwarf_reg;
2714     RegisterInfo sp_reg;
2715     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2716     for (i = 0; i < regs; ++i) {
2717       GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2718       context.SetAddress(addr);
2719       data = MemARead(context, addr, reg_byte_size, 0, &success);
2720       if (!success)
2721         return false;
2722       if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2723         return false;
2724       addr += reg_byte_size;
2725     }
2726 
2727     context.type = EmulateInstruction::eContextAdjustStackPointer;
2728     context.SetImmediateSigned(sp_offset);
2729 
2730     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2731                                LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2732       return false;
2733   }
2734   return true;
2735 }
2736 
2737 // SVC (previously SWI)
EmulateSVC(const uint32_t opcode,const ARMEncoding encoding)2738 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2739                                        const ARMEncoding encoding) {
2740 #if 0
2741     // ARM pseudo code...
2742     if (ConditionPassed())
2743     {
2744         EncodingSpecificOperations();
2745         CallSupervisor();
2746     }
2747 #endif
2748 
2749   bool success = false;
2750 
2751   if (ConditionPassed(opcode)) {
2752     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2753     addr_t lr; // next instruction address
2754     if (!success)
2755       return false;
2756     uint32_t imm32; // the immediate constant
2757     uint32_t mode;  // ARM or Thumb mode
2758     switch (encoding) {
2759     case eEncodingT1:
2760       lr = (pc + 2) | 1u; // return address
2761       imm32 = Bits32(opcode, 7, 0);
2762       mode = eModeThumb;
2763       break;
2764     case eEncodingA1:
2765       lr = pc + 4; // return address
2766       imm32 = Bits32(opcode, 23, 0);
2767       mode = eModeARM;
2768       break;
2769     default:
2770       return false;
2771     }
2772 
2773     EmulateInstruction::Context context;
2774     context.type = EmulateInstruction::eContextSupervisorCall;
2775     context.SetISAAndImmediate(mode, imm32);
2776     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2777                                LLDB_REGNUM_GENERIC_RA, lr))
2778       return false;
2779   }
2780   return true;
2781 }
2782 
2783 // If Then makes up to four following instructions (the IT block) conditional.
EmulateIT(const uint32_t opcode,const ARMEncoding encoding)2784 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2785                                       const ARMEncoding encoding) {
2786 #if 0
2787     // ARM pseudo code...
2788     EncodingSpecificOperations();
2789     ITSTATE.IT<7:0> = firstcond:mask;
2790 #endif
2791 
2792   m_it_session.InitIT(Bits32(opcode, 7, 0));
2793   return true;
2794 }
2795 
EmulateNop(const uint32_t opcode,const ARMEncoding encoding)2796 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2797                                        const ARMEncoding encoding) {
2798   // NOP, nothing to do...
2799   return true;
2800 }
2801 
2802 // Branch causes a branch to a target address.
EmulateB(const uint32_t opcode,const ARMEncoding encoding)2803 bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2804                                      const ARMEncoding encoding) {
2805 #if 0
2806     // ARM pseudo code...
2807     if (ConditionPassed())
2808     {
2809         EncodingSpecificOperations();
2810         BranchWritePC(PC + imm32);
2811     }
2812 #endif
2813 
2814   bool success = false;
2815 
2816   if (ConditionPassed(opcode)) {
2817     EmulateInstruction::Context context;
2818     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2819     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2820     if (!success)
2821       return false;
2822     addr_t target; // target address
2823     int32_t imm32; // PC-relative offset
2824     switch (encoding) {
2825     case eEncodingT1:
2826       // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2827       imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2828       target = pc + imm32;
2829       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2830       break;
2831     case eEncodingT2:
2832       imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2833       target = pc + imm32;
2834       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2835       break;
2836     case eEncodingT3:
2837       // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2838       {
2839         if (Bits32(opcode, 25, 23) == 7)
2840           return false; // See Branches and miscellaneous control on page
2841                         // A6-235.
2842 
2843         uint32_t S = Bit32(opcode, 26);
2844         uint32_t imm6 = Bits32(opcode, 21, 16);
2845         uint32_t J1 = Bit32(opcode, 13);
2846         uint32_t J2 = Bit32(opcode, 11);
2847         uint32_t imm11 = Bits32(opcode, 10, 0);
2848         uint32_t imm21 =
2849             (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2850         imm32 = llvm::SignExtend32<21>(imm21);
2851         target = pc + imm32;
2852         context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2853         break;
2854       }
2855     case eEncodingT4: {
2856       uint32_t S = Bit32(opcode, 26);
2857       uint32_t imm10 = Bits32(opcode, 25, 16);
2858       uint32_t J1 = Bit32(opcode, 13);
2859       uint32_t J2 = Bit32(opcode, 11);
2860       uint32_t imm11 = Bits32(opcode, 10, 0);
2861       uint32_t I1 = !(J1 ^ S);
2862       uint32_t I2 = !(J2 ^ S);
2863       uint32_t imm25 =
2864           (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2865       imm32 = llvm::SignExtend32<25>(imm25);
2866       target = pc + imm32;
2867       context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2868       break;
2869     }
2870     case eEncodingA1:
2871       imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2872       target = pc + imm32;
2873       context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2874       break;
2875     default:
2876       return false;
2877     }
2878     if (!BranchWritePC(context, target))
2879       return false;
2880   }
2881   return true;
2882 }
2883 
2884 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2885 // value in a register with zero and conditionally branch forward a constant
2886 // value.  They do not affect the condition flags. CBNZ, CBZ
EmulateCB(const uint32_t opcode,const ARMEncoding encoding)2887 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2888                                       const ARMEncoding encoding) {
2889 #if 0
2890     // ARM pseudo code...
2891     EncodingSpecificOperations();
2892     if nonzero ^ IsZero(R[n]) then
2893         BranchWritePC(PC + imm32);
2894 #endif
2895 
2896   bool success = false;
2897 
2898   // Read the register value from the operand register Rn.
2899   uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2900   if (!success)
2901     return false;
2902 
2903   EmulateInstruction::Context context;
2904   context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2905   const uint32_t pc = ReadCoreReg(PC_REG, &success);
2906   if (!success)
2907     return false;
2908 
2909   addr_t target;  // target address
2910   uint32_t imm32; // PC-relative offset to branch forward
2911   bool nonzero;
2912   switch (encoding) {
2913   case eEncodingT1:
2914     imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2915     nonzero = BitIsSet(opcode, 11);
2916     target = pc + imm32;
2917     context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2918     break;
2919   default:
2920     return false;
2921   }
2922   if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2923     if (!BranchWritePC(context, target))
2924       return false;
2925 
2926   return true;
2927 }
2928 
2929 // Table Branch Byte causes a PC-relative forward branch using a table of
2930 // single byte offsets.
2931 // A base register provides a pointer to the table, and a second register
2932 // supplies an index into the table.
2933 // The branch length is twice the value of the byte returned from the table.
2934 //
2935 // Table Branch Halfword causes a PC-relative forward branch using a table of
2936 // single halfword offsets.
2937 // A base register provides a pointer to the table, and a second register
2938 // supplies an index into the table.
2939 // The branch length is twice the value of the halfword returned from the
2940 // table. TBB, TBH
EmulateTB(const uint32_t opcode,const ARMEncoding encoding)2941 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2942                                       const ARMEncoding encoding) {
2943 #if 0
2944     // ARM pseudo code...
2945     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2946     if is_tbh then
2947         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2948     else
2949         halfwords = UInt(MemU[R[n]+R[m], 1]);
2950     BranchWritePC(PC + 2*halfwords);
2951 #endif
2952 
2953   bool success = false;
2954 
2955   if (ConditionPassed(opcode)) {
2956     uint32_t Rn; // the base register which contains the address of the table of
2957                  // branch lengths
2958     uint32_t Rm; // the index register which contains an integer pointing to a
2959                  // byte/halfword in the table
2960     bool is_tbh; // true if table branch halfword
2961     switch (encoding) {
2962     case eEncodingT1:
2963       Rn = Bits32(opcode, 19, 16);
2964       Rm = Bits32(opcode, 3, 0);
2965       is_tbh = BitIsSet(opcode, 4);
2966       if (Rn == 13 || BadReg(Rm))
2967         return false;
2968       if (InITBlock() && !LastInITBlock())
2969         return false;
2970       break;
2971     default:
2972       return false;
2973     }
2974 
2975     // Read the address of the table from the operand register Rn. The PC can
2976     // be used, in which case the table immediately follows this instruction.
2977     uint32_t base = ReadCoreReg(Rn, &success);
2978     if (!success)
2979       return false;
2980 
2981     // the table index
2982     uint32_t index = ReadCoreReg(Rm, &success);
2983     if (!success)
2984       return false;
2985 
2986     // the offsetted table address
2987     addr_t addr = base + (is_tbh ? index * 2 : index);
2988 
2989     // PC-relative offset to branch forward
2990     EmulateInstruction::Context context;
2991     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2992     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2993     if (!success)
2994       return false;
2995 
2996     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2997     if (!success)
2998       return false;
2999 
3000     // target address
3001     addr_t target = pc + offset;
3002     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3003     context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3004 
3005     if (!BranchWritePC(context, target))
3006       return false;
3007   }
3008 
3009   return true;
3010 }
3011 
3012 // This instruction adds an immediate value to a register value, and writes the
3013 // result to the destination register. It can optionally update the condition
3014 // flags based on the result.
EmulateADDImmThumb(const uint32_t opcode,const ARMEncoding encoding)3015 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3016                                                const ARMEncoding encoding) {
3017 #if 0
3018     if ConditionPassed() then
3019         EncodingSpecificOperations();
3020         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3021         R[d] = result;
3022         if setflags then
3023             APSR.N = result<31>;
3024             APSR.Z = IsZeroBit(result);
3025             APSR.C = carry;
3026             APSR.V = overflow;
3027 #endif
3028 
3029   bool success = false;
3030 
3031   if (ConditionPassed(opcode)) {
3032     uint32_t d;
3033     uint32_t n;
3034     bool setflags;
3035     uint32_t imm32;
3036     uint32_t carry_out;
3037 
3038     // EncodingSpecificOperations();
3039     switch (encoding) {
3040     case eEncodingT1:
3041       // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3042       // ZeroExtend(imm3, 32);
3043       d = Bits32(opcode, 2, 0);
3044       n = Bits32(opcode, 5, 3);
3045       setflags = !InITBlock();
3046       imm32 = Bits32(opcode, 8, 6);
3047 
3048       break;
3049 
3050     case eEncodingT2:
3051       // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3052       // ZeroExtend(imm8, 32);
3053       d = Bits32(opcode, 10, 8);
3054       n = Bits32(opcode, 10, 8);
3055       setflags = !InITBlock();
3056       imm32 = Bits32(opcode, 7, 0);
3057 
3058       break;
3059 
3060     case eEncodingT3:
3061       // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3062       // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3063       // ThumbExpandImm(i:imm3:imm8);
3064       d = Bits32(opcode, 11, 8);
3065       n = Bits32(opcode, 19, 16);
3066       setflags = BitIsSet(opcode, 20);
3067       imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3068 
3069       // if Rn == '1101' then SEE ADD (SP plus immediate);
3070       if (n == 13)
3071         return EmulateADDSPImm(opcode, eEncodingT3);
3072 
3073       // if BadReg(d) || n == 15 then UNPREDICTABLE;
3074       if (BadReg(d) || (n == 15))
3075         return false;
3076 
3077       break;
3078 
3079     case eEncodingT4: {
3080       // if Rn == '1111' then SEE ADR;
3081       // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3082       // ZeroExtend(i:imm3:imm8, 32);
3083       d = Bits32(opcode, 11, 8);
3084       n = Bits32(opcode, 19, 16);
3085       setflags = false;
3086       uint32_t i = Bit32(opcode, 26);
3087       uint32_t imm3 = Bits32(opcode, 14, 12);
3088       uint32_t imm8 = Bits32(opcode, 7, 0);
3089       imm32 = (i << 11) | (imm3 << 8) | imm8;
3090 
3091       // if Rn == '1101' then SEE ADD (SP plus immediate);
3092       if (n == 13)
3093         return EmulateADDSPImm(opcode, eEncodingT4);
3094 
3095       // if BadReg(d) then UNPREDICTABLE;
3096       if (BadReg(d))
3097         return false;
3098 
3099       break;
3100     }
3101 
3102     default:
3103       return false;
3104     }
3105 
3106     uint64_t Rn =
3107         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3108     if (!success)
3109       return false;
3110 
3111     //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3112     AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3113 
3114     RegisterInfo reg_n;
3115     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3116 
3117     EmulateInstruction::Context context;
3118     context.type = eContextArithmetic;
3119     context.SetRegisterPlusOffset(reg_n, imm32);
3120 
3121     // R[d] = result;
3122     // if setflags then
3123     // APSR.N = result<31>;
3124     // APSR.Z = IsZeroBit(result);
3125     // APSR.C = carry;
3126     // APSR.V = overflow;
3127     if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3128                                    res.carry_out, res.overflow))
3129       return false;
3130   }
3131   return true;
3132 }
3133 
3134 // This instruction adds an immediate value to a register value, and writes the
3135 // result to the destination register.  It can optionally update the condition
3136 // flags based on the result.
EmulateADDImmARM(const uint32_t opcode,const ARMEncoding encoding)3137 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3138                                              const ARMEncoding encoding) {
3139 #if 0
3140     // ARM pseudo code...
3141     if ConditionPassed() then
3142         EncodingSpecificOperations();
3143         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3144         if d == 15 then
3145             ALUWritePC(result); // setflags is always FALSE here
3146         else
3147             R[d] = result;
3148             if setflags then
3149                 APSR.N = result<31>;
3150                 APSR.Z = IsZeroBit(result);
3151                 APSR.C = carry;
3152                 APSR.V = overflow;
3153 #endif
3154 
3155   bool success = false;
3156 
3157   if (ConditionPassed(opcode)) {
3158     uint32_t Rd, Rn;
3159     uint32_t
3160         imm32; // the immediate value to be added to the value obtained from Rn
3161     bool setflags;
3162     switch (encoding) {
3163     case eEncodingA1:
3164       Rd = Bits32(opcode, 15, 12);
3165       Rn = Bits32(opcode, 19, 16);
3166       setflags = BitIsSet(opcode, 20);
3167       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3168       break;
3169     default:
3170       return false;
3171     }
3172 
3173     // Read the first operand.
3174     uint32_t val1 = ReadCoreReg(Rn, &success);
3175     if (!success)
3176       return false;
3177 
3178     AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3179 
3180     EmulateInstruction::Context context;
3181     if (Rd == 13)
3182       context.type = EmulateInstruction::eContextAdjustStackPointer;
3183     else if (Rd == GetFramePointerRegisterNumber())
3184       context.type = EmulateInstruction::eContextSetFramePointer;
3185     else
3186       context.type = EmulateInstruction::eContextRegisterPlusOffset;
3187 
3188     RegisterInfo dwarf_reg;
3189     GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3190     context.SetRegisterPlusOffset(dwarf_reg, imm32);
3191 
3192     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3193                                    res.carry_out, res.overflow))
3194       return false;
3195   }
3196   return true;
3197 }
3198 
3199 // This instruction adds a register value and an optionally-shifted register
3200 // value, and writes the result to the destination register. It can optionally
3201 // update the condition flags based on the result.
EmulateADDReg(const uint32_t opcode,const ARMEncoding encoding)3202 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3203                                           const ARMEncoding encoding) {
3204 #if 0
3205     // ARM pseudo code...
3206     if ConditionPassed() then
3207         EncodingSpecificOperations();
3208         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3209         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3210         if d == 15 then
3211             ALUWritePC(result); // setflags is always FALSE here
3212         else
3213             R[d] = result;
3214             if setflags then
3215                 APSR.N = result<31>;
3216                 APSR.Z = IsZeroBit(result);
3217                 APSR.C = carry;
3218                 APSR.V = overflow;
3219 #endif
3220 
3221   bool success = false;
3222 
3223   if (ConditionPassed(opcode)) {
3224     uint32_t Rd, Rn, Rm;
3225     ARM_ShifterType shift_t;
3226     uint32_t shift_n; // the shift applied to the value read from Rm
3227     bool setflags;
3228     switch (encoding) {
3229     case eEncodingT1:
3230       Rd = Bits32(opcode, 2, 0);
3231       Rn = Bits32(opcode, 5, 3);
3232       Rm = Bits32(opcode, 8, 6);
3233       setflags = !InITBlock();
3234       shift_t = SRType_LSL;
3235       shift_n = 0;
3236       break;
3237     case eEncodingT2:
3238       Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3239       Rm = Bits32(opcode, 6, 3);
3240       setflags = false;
3241       shift_t = SRType_LSL;
3242       shift_n = 0;
3243       if (Rn == 15 && Rm == 15)
3244         return false;
3245       if (Rd == 15 && InITBlock() && !LastInITBlock())
3246         return false;
3247       break;
3248     case eEncodingA1:
3249       Rd = Bits32(opcode, 15, 12);
3250       Rn = Bits32(opcode, 19, 16);
3251       Rm = Bits32(opcode, 3, 0);
3252       setflags = BitIsSet(opcode, 20);
3253       shift_n = DecodeImmShiftARM(opcode, shift_t);
3254       break;
3255     default:
3256       return false;
3257     }
3258 
3259     // Read the first operand.
3260     uint32_t val1 = ReadCoreReg(Rn, &success);
3261     if (!success)
3262       return false;
3263 
3264     // Read the second operand.
3265     uint32_t val2 = ReadCoreReg(Rm, &success);
3266     if (!success)
3267       return false;
3268 
3269     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3270     if (!success)
3271       return false;
3272     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3273 
3274     EmulateInstruction::Context context;
3275     context.type = eContextArithmetic;
3276     RegisterInfo op1_reg;
3277     RegisterInfo op2_reg;
3278     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3279     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3280     context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3281 
3282     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3283                                    res.carry_out, res.overflow))
3284       return false;
3285   }
3286   return true;
3287 }
3288 
3289 // Compare Negative (immediate) adds a register value and an immediate value.
3290 // It updates the condition flags based on the result, and discards the result.
EmulateCMNImm(const uint32_t opcode,const ARMEncoding encoding)3291 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3292                                           const ARMEncoding encoding) {
3293 #if 0
3294     // ARM pseudo code...
3295     if ConditionPassed() then
3296         EncodingSpecificOperations();
3297         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3298         APSR.N = result<31>;
3299         APSR.Z = IsZeroBit(result);
3300         APSR.C = carry;
3301         APSR.V = overflow;
3302 #endif
3303 
3304   bool success = false;
3305 
3306   uint32_t Rn;    // the first operand
3307   uint32_t imm32; // the immediate value to be compared with
3308   switch (encoding) {
3309   case eEncodingT1:
3310     Rn = Bits32(opcode, 19, 16);
3311     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3312     if (Rn == 15)
3313       return false;
3314     break;
3315   case eEncodingA1:
3316     Rn = Bits32(opcode, 19, 16);
3317     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3318     break;
3319   default:
3320     return false;
3321   }
3322   // Read the register value from the operand register Rn.
3323   uint32_t reg_val = ReadCoreReg(Rn, &success);
3324   if (!success)
3325     return false;
3326 
3327   AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3328 
3329   EmulateInstruction::Context context;
3330   context.type = EmulateInstruction::eContextImmediate;
3331   context.SetNoArgs();
3332   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3333 }
3334 
3335 // Compare Negative (register) adds a register value and an optionally-shifted
3336 // register value. It updates the condition flags based on the result, and
3337 // discards the result.
EmulateCMNReg(const uint32_t opcode,const ARMEncoding encoding)3338 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3339                                           const ARMEncoding encoding) {
3340 #if 0
3341     // ARM pseudo code...
3342     if ConditionPassed() then
3343         EncodingSpecificOperations();
3344         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3345         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3346         APSR.N = result<31>;
3347         APSR.Z = IsZeroBit(result);
3348         APSR.C = carry;
3349         APSR.V = overflow;
3350 #endif
3351 
3352   bool success = false;
3353 
3354   uint32_t Rn; // the first operand
3355   uint32_t Rm; // the second operand
3356   ARM_ShifterType shift_t;
3357   uint32_t shift_n; // the shift applied to the value read from Rm
3358   switch (encoding) {
3359   case eEncodingT1:
3360     Rn = Bits32(opcode, 2, 0);
3361     Rm = Bits32(opcode, 5, 3);
3362     shift_t = SRType_LSL;
3363     shift_n = 0;
3364     break;
3365   case eEncodingT2:
3366     Rn = Bits32(opcode, 19, 16);
3367     Rm = Bits32(opcode, 3, 0);
3368     shift_n = DecodeImmShiftThumb(opcode, shift_t);
3369     // if n == 15 || BadReg(m) then UNPREDICTABLE;
3370     if (Rn == 15 || BadReg(Rm))
3371       return false;
3372     break;
3373   case eEncodingA1:
3374     Rn = Bits32(opcode, 19, 16);
3375     Rm = Bits32(opcode, 3, 0);
3376     shift_n = DecodeImmShiftARM(opcode, shift_t);
3377     break;
3378   default:
3379     return false;
3380   }
3381   // Read the register value from register Rn.
3382   uint32_t val1 = ReadCoreReg(Rn, &success);
3383   if (!success)
3384     return false;
3385 
3386   // Read the register value from register Rm.
3387   uint32_t val2 = ReadCoreReg(Rm, &success);
3388   if (!success)
3389     return false;
3390 
3391   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3392   if (!success)
3393     return false;
3394   AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3395 
3396   EmulateInstruction::Context context;
3397   context.type = EmulateInstruction::eContextImmediate;
3398   context.SetNoArgs();
3399   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3400 }
3401 
3402 // Compare (immediate) subtracts an immediate value from a register value. It
3403 // updates the condition flags based on the result, and discards the result.
EmulateCMPImm(const uint32_t opcode,const ARMEncoding encoding)3404 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3405                                           const ARMEncoding encoding) {
3406 #if 0
3407     // ARM pseudo code...
3408     if ConditionPassed() then
3409         EncodingSpecificOperations();
3410         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3411         APSR.N = result<31>;
3412         APSR.Z = IsZeroBit(result);
3413         APSR.C = carry;
3414         APSR.V = overflow;
3415 #endif
3416 
3417   bool success = false;
3418 
3419   uint32_t Rn;    // the first operand
3420   uint32_t imm32; // the immediate value to be compared with
3421   switch (encoding) {
3422   case eEncodingT1:
3423     Rn = Bits32(opcode, 10, 8);
3424     imm32 = Bits32(opcode, 7, 0);
3425     break;
3426   case eEncodingT2:
3427     Rn = Bits32(opcode, 19, 16);
3428     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3429     if (Rn == 15)
3430       return false;
3431     break;
3432   case eEncodingA1:
3433     Rn = Bits32(opcode, 19, 16);
3434     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3435     break;
3436   default:
3437     return false;
3438   }
3439   // Read the register value from the operand register Rn.
3440   uint32_t reg_val = ReadCoreReg(Rn, &success);
3441   if (!success)
3442     return false;
3443 
3444   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3445 
3446   EmulateInstruction::Context context;
3447   context.type = EmulateInstruction::eContextImmediate;
3448   context.SetNoArgs();
3449   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3450 }
3451 
3452 // Compare (register) subtracts an optionally-shifted register value from a
3453 // register value. It updates the condition flags based on the result, and
3454 // discards the result.
EmulateCMPReg(const uint32_t opcode,const ARMEncoding encoding)3455 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3456                                           const ARMEncoding encoding) {
3457 #if 0
3458     // ARM pseudo code...
3459     if ConditionPassed() then
3460         EncodingSpecificOperations();
3461         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3462         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3463         APSR.N = result<31>;
3464         APSR.Z = IsZeroBit(result);
3465         APSR.C = carry;
3466         APSR.V = overflow;
3467 #endif
3468 
3469   bool success = false;
3470 
3471   uint32_t Rn; // the first operand
3472   uint32_t Rm; // the second operand
3473   ARM_ShifterType shift_t;
3474   uint32_t shift_n; // the shift applied to the value read from Rm
3475   switch (encoding) {
3476   case eEncodingT1:
3477     Rn = Bits32(opcode, 2, 0);
3478     Rm = Bits32(opcode, 5, 3);
3479     shift_t = SRType_LSL;
3480     shift_n = 0;
3481     break;
3482   case eEncodingT2:
3483     Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3484     Rm = Bits32(opcode, 6, 3);
3485     shift_t = SRType_LSL;
3486     shift_n = 0;
3487     if (Rn < 8 && Rm < 8)
3488       return false;
3489     if (Rn == 15 || Rm == 15)
3490       return false;
3491     break;
3492   case eEncodingT3:
3493     Rn = Bits32(opcode, 19, 16);
3494     Rm = Bits32(opcode, 3, 0);
3495     shift_n = DecodeImmShiftThumb(opcode, shift_t);
3496     if (Rn == 15 || BadReg(Rm))
3497       return false;
3498     break;
3499   case eEncodingA1:
3500     Rn = Bits32(opcode, 19, 16);
3501     Rm = Bits32(opcode, 3, 0);
3502     shift_n = DecodeImmShiftARM(opcode, shift_t);
3503     break;
3504   default:
3505     return false;
3506   }
3507   // Read the register value from register Rn.
3508   uint32_t val1 = ReadCoreReg(Rn, &success);
3509   if (!success)
3510     return false;
3511 
3512   // Read the register value from register Rm.
3513   uint32_t val2 = ReadCoreReg(Rm, &success);
3514   if (!success)
3515     return false;
3516 
3517   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3518   if (!success)
3519     return false;
3520   AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3521 
3522   EmulateInstruction::Context context;
3523   context.type = EmulateInstruction::eContextImmediate;
3524   context.SetNoArgs();
3525   return WriteFlags(context, res.result, res.carry_out, res.overflow);
3526 }
3527 
3528 // Arithmetic Shift Right (immediate) shifts a register value right by an
3529 // immediate number of bits, shifting in copies of its sign bit, and writes the
3530 // result to the destination register.  It can optionally update the condition
3531 // flags based on the result.
EmulateASRImm(const uint32_t opcode,const ARMEncoding encoding)3532 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3533                                           const ARMEncoding encoding) {
3534 #if 0
3535     // ARM pseudo code...
3536     if ConditionPassed() then
3537         EncodingSpecificOperations();
3538         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3539         if d == 15 then         // Can only occur for ARM encoding
3540             ALUWritePC(result); // setflags is always FALSE here
3541         else
3542             R[d] = result;
3543             if setflags then
3544                 APSR.N = result<31>;
3545                 APSR.Z = IsZeroBit(result);
3546                 APSR.C = carry;
3547                 // APSR.V unchanged
3548 #endif
3549 
3550   return EmulateShiftImm(opcode, encoding, SRType_ASR);
3551 }
3552 
3553 // Arithmetic Shift Right (register) shifts a register value right by a
3554 // variable number of bits, shifting in copies of its sign bit, and writes the
3555 // result to the destination register. The variable number of bits is read from
3556 // the bottom byte of a register. It can optionally update the condition flags
3557 // based on the result.
EmulateASRReg(const uint32_t opcode,const ARMEncoding encoding)3558 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3559                                           const ARMEncoding encoding) {
3560 #if 0
3561     // ARM pseudo code...
3562     if ConditionPassed() then
3563         EncodingSpecificOperations();
3564         shift_n = UInt(R[m]<7:0>);
3565         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3566         R[d] = result;
3567         if setflags then
3568             APSR.N = result<31>;
3569             APSR.Z = IsZeroBit(result);
3570             APSR.C = carry;
3571             // APSR.V unchanged
3572 #endif
3573 
3574   return EmulateShiftReg(opcode, encoding, SRType_ASR);
3575 }
3576 
3577 // Logical Shift Left (immediate) shifts a register value left by an immediate
3578 // number of bits, shifting in zeros, and writes the result to the destination
3579 // register.  It can optionally update the condition flags based on the result.
EmulateLSLImm(const uint32_t opcode,const ARMEncoding encoding)3580 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3581                                           const ARMEncoding encoding) {
3582 #if 0
3583     // ARM pseudo code...
3584     if ConditionPassed() then
3585         EncodingSpecificOperations();
3586         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3587         if d == 15 then         // Can only occur for ARM encoding
3588             ALUWritePC(result); // setflags is always FALSE here
3589         else
3590             R[d] = result;
3591             if setflags then
3592                 APSR.N = result<31>;
3593                 APSR.Z = IsZeroBit(result);
3594                 APSR.C = carry;
3595                 // APSR.V unchanged
3596 #endif
3597 
3598   return EmulateShiftImm(opcode, encoding, SRType_LSL);
3599 }
3600 
3601 // Logical Shift Left (register) shifts a register value left by a variable
3602 // number of bits, shifting in zeros, and writes the result to the destination
3603 // register.  The variable number of bits is read from the bottom byte of a
3604 // register. It can optionally update the condition flags based on the result.
EmulateLSLReg(const uint32_t opcode,const ARMEncoding encoding)3605 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3606                                           const ARMEncoding encoding) {
3607 #if 0
3608     // ARM pseudo code...
3609     if ConditionPassed() then
3610         EncodingSpecificOperations();
3611         shift_n = UInt(R[m]<7:0>);
3612         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3613         R[d] = result;
3614         if setflags then
3615             APSR.N = result<31>;
3616             APSR.Z = IsZeroBit(result);
3617             APSR.C = carry;
3618             // APSR.V unchanged
3619 #endif
3620 
3621   return EmulateShiftReg(opcode, encoding, SRType_LSL);
3622 }
3623 
3624 // Logical Shift Right (immediate) shifts a register value right by an
3625 // immediate number of bits, shifting in zeros, and writes the result to the
3626 // destination register.  It can optionally update the condition flags based on
3627 // the result.
EmulateLSRImm(const uint32_t opcode,const ARMEncoding encoding)3628 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3629                                           const ARMEncoding encoding) {
3630 #if 0
3631     // ARM pseudo code...
3632     if ConditionPassed() then
3633         EncodingSpecificOperations();
3634         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3635         if d == 15 then         // Can only occur for ARM encoding
3636             ALUWritePC(result); // setflags is always FALSE here
3637         else
3638             R[d] = result;
3639             if setflags then
3640                 APSR.N = result<31>;
3641                 APSR.Z = IsZeroBit(result);
3642                 APSR.C = carry;
3643                 // APSR.V unchanged
3644 #endif
3645 
3646   return EmulateShiftImm(opcode, encoding, SRType_LSR);
3647 }
3648 
3649 // Logical Shift Right (register) shifts a register value right by a variable
3650 // number of bits, shifting in zeros, and writes the result to the destination
3651 // register.  The variable number of bits is read from the bottom byte of a
3652 // register. It can optionally update the condition flags based on the result.
EmulateLSRReg(const uint32_t opcode,const ARMEncoding encoding)3653 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3654                                           const ARMEncoding encoding) {
3655 #if 0
3656     // ARM pseudo code...
3657     if ConditionPassed() then
3658         EncodingSpecificOperations();
3659         shift_n = UInt(R[m]<7:0>);
3660         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3661         R[d] = result;
3662         if setflags then
3663             APSR.N = result<31>;
3664             APSR.Z = IsZeroBit(result);
3665             APSR.C = carry;
3666             // APSR.V unchanged
3667 #endif
3668 
3669   return EmulateShiftReg(opcode, encoding, SRType_LSR);
3670 }
3671 
3672 // Rotate Right (immediate) provides the value of the contents of a register
3673 // rotated by a constant value. The bits that are rotated off the right end are
3674 // inserted into the vacated bit positions on the left. It can optionally
3675 // update the condition flags based on the result.
EmulateRORImm(const uint32_t opcode,const ARMEncoding encoding)3676 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3677                                           const ARMEncoding encoding) {
3678 #if 0
3679     // ARM pseudo code...
3680     if ConditionPassed() then
3681         EncodingSpecificOperations();
3682         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3683         if d == 15 then         // Can only occur for ARM encoding
3684             ALUWritePC(result); // setflags is always FALSE here
3685         else
3686             R[d] = result;
3687             if setflags then
3688                 APSR.N = result<31>;
3689                 APSR.Z = IsZeroBit(result);
3690                 APSR.C = carry;
3691                 // APSR.V unchanged
3692 #endif
3693 
3694   return EmulateShiftImm(opcode, encoding, SRType_ROR);
3695 }
3696 
3697 // Rotate Right (register) provides the value of the contents of a register
3698 // rotated by a variable number of bits. The bits that are rotated off the
3699 // right end are inserted into the vacated bit positions on the left. The
3700 // variable number of bits is read from the bottom byte of a register. It can
3701 // optionally update the condition flags based on the result.
EmulateRORReg(const uint32_t opcode,const ARMEncoding encoding)3702 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3703                                           const ARMEncoding encoding) {
3704 #if 0
3705     // ARM pseudo code...
3706     if ConditionPassed() then
3707         EncodingSpecificOperations();
3708         shift_n = UInt(R[m]<7:0>);
3709         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3710         R[d] = result;
3711         if setflags then
3712             APSR.N = result<31>;
3713             APSR.Z = IsZeroBit(result);
3714             APSR.C = carry;
3715             // APSR.V unchanged
3716 #endif
3717 
3718   return EmulateShiftReg(opcode, encoding, SRType_ROR);
3719 }
3720 
3721 // Rotate Right with Extend provides the value of the contents of a register
3722 // shifted right by one place, with the carry flag shifted into bit [31].
3723 //
3724 // RRX can optionally update the condition flags based on the result.
3725 // In that case, bit [0] is shifted into the carry flag.
EmulateRRX(const uint32_t opcode,const ARMEncoding encoding)3726 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3727                                        const ARMEncoding encoding) {
3728 #if 0
3729     // ARM pseudo code...
3730     if ConditionPassed() then
3731         EncodingSpecificOperations();
3732         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3733         if d == 15 then         // Can only occur for ARM encoding
3734             ALUWritePC(result); // setflags is always FALSE here
3735         else
3736             R[d] = result;
3737             if setflags then
3738                 APSR.N = result<31>;
3739                 APSR.Z = IsZeroBit(result);
3740                 APSR.C = carry;
3741                 // APSR.V unchanged
3742 #endif
3743 
3744   return EmulateShiftImm(opcode, encoding, SRType_RRX);
3745 }
3746 
EmulateShiftImm(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3747 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3748                                             const ARMEncoding encoding,
3749                                             ARM_ShifterType shift_type) {
3750   //    assert(shift_type == SRType_ASR
3751   //           || shift_type == SRType_LSL
3752   //           || shift_type == SRType_LSR
3753   //           || shift_type == SRType_ROR
3754   //           || shift_type == SRType_RRX);
3755 
3756   bool success = false;
3757 
3758   if (ConditionPassed(opcode)) {
3759     uint32_t Rd;    // the destination register
3760     uint32_t Rm;    // the first operand register
3761     uint32_t imm5;  // encoding for the shift amount
3762     uint32_t carry; // the carry bit after the shift operation
3763     bool setflags;
3764 
3765     // Special case handling!
3766     // A8.6.139 ROR (immediate) -- Encoding T1
3767     ARMEncoding use_encoding = encoding;
3768     if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3769       // Morph the T1 encoding from the ARM Architecture Manual into T2
3770       // encoding to have the same decoding of bit fields as the other Thumb2
3771       // shift operations.
3772       use_encoding = eEncodingT2;
3773     }
3774 
3775     switch (use_encoding) {
3776     case eEncodingT1:
3777       // Due to the above special case handling!
3778       if (shift_type == SRType_ROR)
3779         return false;
3780 
3781       Rd = Bits32(opcode, 2, 0);
3782       Rm = Bits32(opcode, 5, 3);
3783       setflags = !InITBlock();
3784       imm5 = Bits32(opcode, 10, 6);
3785       break;
3786     case eEncodingT2:
3787       // A8.6.141 RRX
3788       // There's no imm form of RRX instructions.
3789       if (shift_type == SRType_RRX)
3790         return false;
3791 
3792       Rd = Bits32(opcode, 11, 8);
3793       Rm = Bits32(opcode, 3, 0);
3794       setflags = BitIsSet(opcode, 20);
3795       imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3796       if (BadReg(Rd) || BadReg(Rm))
3797         return false;
3798       break;
3799     case eEncodingA1:
3800       Rd = Bits32(opcode, 15, 12);
3801       Rm = Bits32(opcode, 3, 0);
3802       setflags = BitIsSet(opcode, 20);
3803       imm5 = Bits32(opcode, 11, 7);
3804       break;
3805     default:
3806       return false;
3807     }
3808 
3809     // A8.6.139 ROR (immediate)
3810     if (shift_type == SRType_ROR && imm5 == 0)
3811       shift_type = SRType_RRX;
3812 
3813     // Get the first operand.
3814     uint32_t value = ReadCoreReg(Rm, &success);
3815     if (!success)
3816       return false;
3817 
3818     // Decode the shift amount if not RRX.
3819     uint32_t amt =
3820         (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3821 
3822     uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3823     if (!success)
3824       return false;
3825 
3826     // The context specifies that an immediate is to be moved into Rd.
3827     EmulateInstruction::Context context;
3828     context.type = EmulateInstruction::eContextImmediate;
3829     context.SetNoArgs();
3830 
3831     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3832       return false;
3833   }
3834   return true;
3835 }
3836 
EmulateShiftReg(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3837 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3838                                             const ARMEncoding encoding,
3839                                             ARM_ShifterType shift_type) {
3840   // assert(shift_type == SRType_ASR
3841   //        || shift_type == SRType_LSL
3842   //        || shift_type == SRType_LSR
3843   //        || shift_type == SRType_ROR);
3844 
3845   bool success = false;
3846 
3847   if (ConditionPassed(opcode)) {
3848     uint32_t Rd; // the destination register
3849     uint32_t Rn; // the first operand register
3850     uint32_t
3851         Rm; // the register whose bottom byte contains the amount to shift by
3852     uint32_t carry; // the carry bit after the shift operation
3853     bool setflags;
3854     switch (encoding) {
3855     case eEncodingT1:
3856       Rd = Bits32(opcode, 2, 0);
3857       Rn = Rd;
3858       Rm = Bits32(opcode, 5, 3);
3859       setflags = !InITBlock();
3860       break;
3861     case eEncodingT2:
3862       Rd = Bits32(opcode, 11, 8);
3863       Rn = Bits32(opcode, 19, 16);
3864       Rm = Bits32(opcode, 3, 0);
3865       setflags = BitIsSet(opcode, 20);
3866       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3867         return false;
3868       break;
3869     case eEncodingA1:
3870       Rd = Bits32(opcode, 15, 12);
3871       Rn = Bits32(opcode, 3, 0);
3872       Rm = Bits32(opcode, 11, 8);
3873       setflags = BitIsSet(opcode, 20);
3874       if (Rd == 15 || Rn == 15 || Rm == 15)
3875         return false;
3876       break;
3877     default:
3878       return false;
3879     }
3880 
3881     // Get the first operand.
3882     uint32_t value = ReadCoreReg(Rn, &success);
3883     if (!success)
3884       return false;
3885     // Get the Rm register content.
3886     uint32_t val = ReadCoreReg(Rm, &success);
3887     if (!success)
3888       return false;
3889 
3890     // Get the shift amount.
3891     uint32_t amt = Bits32(val, 7, 0);
3892 
3893     uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3894     if (!success)
3895       return false;
3896 
3897     // The context specifies that an immediate is to be moved into Rd.
3898     EmulateInstruction::Context context;
3899     context.type = EmulateInstruction::eContextImmediate;
3900     context.SetNoArgs();
3901 
3902     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3903       return false;
3904   }
3905   return true;
3906 }
3907 
3908 // LDM loads multiple registers from consecutive memory locations, using an
3909 // address from a base register.  Optionally the address just above the highest
3910 // of those locations can be written back to the base register.
EmulateLDM(const uint32_t opcode,const ARMEncoding encoding)3911 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3912                                        const ARMEncoding encoding) {
3913 #if 0
3914     // ARM pseudo code...
3915     if ConditionPassed()
3916         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3917         address = R[n];
3918 
3919         for i = 0 to 14
3920             if registers<i> == '1' then
3921                 R[i] = MemA[address, 4]; address = address + 4;
3922         if registers<15> == '1' then
3923             LoadWritePC (MemA[address, 4]);
3924 
3925         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3926         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3927 
3928 #endif
3929 
3930   bool success = false;
3931   if (ConditionPassed(opcode)) {
3932     uint32_t n;
3933     uint32_t registers = 0;
3934     bool wback;
3935     const uint32_t addr_byte_size = GetAddressByteSize();
3936     switch (encoding) {
3937     case eEncodingT1:
3938       // n = UInt(Rn); registers = '00000000':register_list; wback =
3939       // (registers<n> == '0');
3940       n = Bits32(opcode, 10, 8);
3941       registers = Bits32(opcode, 7, 0);
3942       registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3943       wback = BitIsClear(registers, n);
3944       // if BitCount(registers) < 1 then UNPREDICTABLE;
3945       if (BitCount(registers) < 1)
3946         return false;
3947       break;
3948     case eEncodingT2:
3949       // if W == '1' && Rn == '1101' then SEE POP;
3950       // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3951       n = Bits32(opcode, 19, 16);
3952       registers = Bits32(opcode, 15, 0);
3953       registers = registers & 0xdfff; // Make sure bit 13 is zero.
3954       wback = BitIsSet(opcode, 21);
3955 
3956       // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3957       // UNPREDICTABLE;
3958       if ((n == 15) || (BitCount(registers) < 2) ||
3959           (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3960         return false;
3961 
3962       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3963       // UNPREDICTABLE;
3964       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3965         return false;
3966 
3967       // if wback && registers<n> == '1' then UNPREDICTABLE;
3968       if (wback && BitIsSet(registers, n))
3969         return false;
3970       break;
3971 
3972     case eEncodingA1:
3973       n = Bits32(opcode, 19, 16);
3974       registers = Bits32(opcode, 15, 0);
3975       wback = BitIsSet(opcode, 21);
3976       if ((n == 15) || (BitCount(registers) < 1))
3977         return false;
3978       break;
3979     default:
3980       return false;
3981     }
3982 
3983     int32_t offset = 0;
3984     const addr_t base_address =
3985         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3986     if (!success)
3987       return false;
3988 
3989     EmulateInstruction::Context context;
3990     context.type = EmulateInstruction::eContextRegisterPlusOffset;
3991     RegisterInfo dwarf_reg;
3992     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3993     context.SetRegisterPlusOffset(dwarf_reg, offset);
3994 
3995     for (int i = 0; i < 14; ++i) {
3996       if (BitIsSet(registers, i)) {
3997         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3998         context.SetRegisterPlusOffset(dwarf_reg, offset);
3999         if (wback && (n == 13)) // Pop Instruction
4000         {
4001           context.type = EmulateInstruction::eContextPopRegisterOffStack;
4002           context.SetAddress(base_address + offset);
4003         }
4004 
4005         // R[i] = MemA [address, 4]; address = address + 4;
4006         uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4007                                  0, &success);
4008         if (!success)
4009           return false;
4010 
4011         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4012                                    data))
4013           return false;
4014 
4015         offset += addr_byte_size;
4016       }
4017     }
4018 
4019     if (BitIsSet(registers, 15)) {
4020       // LoadWritePC (MemA [address, 4]);
4021       context.type = EmulateInstruction::eContextRegisterPlusOffset;
4022       context.SetRegisterPlusOffset(dwarf_reg, offset);
4023       uint32_t data =
4024           MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4025       if (!success)
4026         return false;
4027       // In ARMv5T and above, this is an interworking branch.
4028       if (!LoadWritePC(context, data))
4029         return false;
4030     }
4031 
4032     if (wback && BitIsClear(registers, n)) {
4033       // R[n] = R[n] + 4 * BitCount (registers)
4034       int32_t offset = addr_byte_size * BitCount(registers);
4035       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4036       context.SetRegisterPlusOffset(dwarf_reg, offset);
4037 
4038       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4039                                  base_address + offset))
4040         return false;
4041     }
4042     if (wback && BitIsSet(registers, n))
4043       // R[n] bits(32) UNKNOWN;
4044       return WriteBits32Unknown(n);
4045   }
4046   return true;
4047 }
4048 
4049 // LDMDA loads multiple registers from consecutive memory locations using an
4050 // address from a base register.
4051 // The consecutive memory locations end at this address and the address just
4052 // below the lowest of those locations can optionally be written back to the
4053 // base register.
EmulateLDMDA(const uint32_t opcode,const ARMEncoding encoding)4054 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4055                                          const ARMEncoding encoding) {
4056 #if 0
4057     // ARM pseudo code...
4058     if ConditionPassed() then
4059         EncodingSpecificOperations();
4060         address = R[n] - 4*BitCount(registers) + 4;
4061 
4062         for i = 0 to 14
4063             if registers<i> == '1' then
4064                   R[i] = MemA[address,4]; address = address + 4;
4065 
4066         if registers<15> == '1' then
4067             LoadWritePC(MemA[address,4]);
4068 
4069         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4070         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4071 #endif
4072 
4073   bool success = false;
4074 
4075   if (ConditionPassed(opcode)) {
4076     uint32_t n;
4077     uint32_t registers = 0;
4078     bool wback;
4079     const uint32_t addr_byte_size = GetAddressByteSize();
4080 
4081     // EncodingSpecificOperations();
4082     switch (encoding) {
4083     case eEncodingA1:
4084       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4085       n = Bits32(opcode, 19, 16);
4086       registers = Bits32(opcode, 15, 0);
4087       wback = BitIsSet(opcode, 21);
4088 
4089       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4090       if ((n == 15) || (BitCount(registers) < 1))
4091         return false;
4092 
4093       break;
4094 
4095     default:
4096       return false;
4097     }
4098     // address = R[n] - 4*BitCount(registers) + 4;
4099 
4100     int32_t offset = 0;
4101     addr_t Rn = ReadCoreReg(n, &success);
4102 
4103     if (!success)
4104       return false;
4105 
4106     addr_t address =
4107         Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4108 
4109     EmulateInstruction::Context context;
4110     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4111     RegisterInfo dwarf_reg;
4112     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4113     context.SetRegisterPlusOffset(dwarf_reg, offset);
4114 
4115     // for i = 0 to 14
4116     for (int i = 0; i < 14; ++i) {
4117       // if registers<i> == '1' then
4118       if (BitIsSet(registers, i)) {
4119         // R[i] = MemA[address,4]; address = address + 4;
4120         context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4121         uint32_t data =
4122             MemARead(context, address + offset, addr_byte_size, 0, &success);
4123         if (!success)
4124           return false;
4125         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4126                                    data))
4127           return false;
4128         offset += addr_byte_size;
4129       }
4130     }
4131 
4132     // if registers<15> == '1' then
4133     //     LoadWritePC(MemA[address,4]);
4134     if (BitIsSet(registers, 15)) {
4135       context.SetRegisterPlusOffset(dwarf_reg, offset);
4136       uint32_t data =
4137           MemARead(context, address + offset, addr_byte_size, 0, &success);
4138       if (!success)
4139         return false;
4140       // In ARMv5T and above, this is an interworking branch.
4141       if (!LoadWritePC(context, data))
4142         return false;
4143     }
4144 
4145     // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4146     if (wback && BitIsClear(registers, n)) {
4147       if (!success)
4148         return false;
4149 
4150       offset = (addr_byte_size * BitCount(registers)) * -1;
4151       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4152       context.SetImmediateSigned(offset);
4153       addr_t addr = Rn + offset;
4154       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4155                                  addr))
4156         return false;
4157     }
4158 
4159     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4160     if (wback && BitIsSet(registers, n))
4161       return WriteBits32Unknown(n);
4162   }
4163   return true;
4164 }
4165 
4166 // LDMDB loads multiple registers from consecutive memory locations using an
4167 // address from a base register.  The
4168 // consecutive memory locations end just below this address, and the address of
4169 // the lowest of those locations can be optionally written back to the base
4170 // register.
EmulateLDMDB(const uint32_t opcode,const ARMEncoding encoding)4171 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4172                                          const ARMEncoding encoding) {
4173 #if 0
4174     // ARM pseudo code...
4175     if ConditionPassed() then
4176         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4177         address = R[n] - 4*BitCount(registers);
4178 
4179         for i = 0 to 14
4180             if registers<i> == '1' then
4181                   R[i] = MemA[address,4]; address = address + 4;
4182         if registers<15> == '1' then
4183                   LoadWritePC(MemA[address,4]);
4184 
4185         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4186         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4187 #endif
4188 
4189   bool success = false;
4190 
4191   if (ConditionPassed(opcode)) {
4192     uint32_t n;
4193     uint32_t registers = 0;
4194     bool wback;
4195     const uint32_t addr_byte_size = GetAddressByteSize();
4196     switch (encoding) {
4197     case eEncodingT1:
4198       // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4199       n = Bits32(opcode, 19, 16);
4200       registers = Bits32(opcode, 15, 0);
4201       registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4202       wback = BitIsSet(opcode, 21);
4203 
4204       // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4205       // UNPREDICTABLE;
4206       if ((n == 15) || (BitCount(registers) < 2) ||
4207           (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4208         return false;
4209 
4210       // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4211       // UNPREDICTABLE;
4212       if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4213         return false;
4214 
4215       // if wback && registers<n> == '1' then UNPREDICTABLE;
4216       if (wback && BitIsSet(registers, n))
4217         return false;
4218 
4219       break;
4220 
4221     case eEncodingA1:
4222       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4223       n = Bits32(opcode, 19, 16);
4224       registers = Bits32(opcode, 15, 0);
4225       wback = BitIsSet(opcode, 21);
4226 
4227       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4228       if ((n == 15) || (BitCount(registers) < 1))
4229         return false;
4230 
4231       break;
4232 
4233     default:
4234       return false;
4235     }
4236 
4237     // address = R[n] - 4*BitCount(registers);
4238 
4239     int32_t offset = 0;
4240     addr_t Rn =
4241         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4242 
4243     if (!success)
4244       return false;
4245 
4246     addr_t address = Rn - (addr_byte_size * BitCount(registers));
4247     EmulateInstruction::Context context;
4248     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4249     RegisterInfo dwarf_reg;
4250     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4251     context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4252 
4253     for (int i = 0; i < 14; ++i) {
4254       if (BitIsSet(registers, i)) {
4255         // R[i] = MemA[address,4]; address = address + 4;
4256         context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4257         uint32_t data =
4258             MemARead(context, address + offset, addr_byte_size, 0, &success);
4259         if (!success)
4260           return false;
4261 
4262         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4263                                    data))
4264           return false;
4265 
4266         offset += addr_byte_size;
4267       }
4268     }
4269 
4270     // if registers<15> == '1' then
4271     //     LoadWritePC(MemA[address,4]);
4272     if (BitIsSet(registers, 15)) {
4273       context.SetRegisterPlusOffset(dwarf_reg, offset);
4274       uint32_t data =
4275           MemARead(context, address + offset, addr_byte_size, 0, &success);
4276       if (!success)
4277         return false;
4278       // In ARMv5T and above, this is an interworking branch.
4279       if (!LoadWritePC(context, data))
4280         return false;
4281     }
4282 
4283     // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4284     if (wback && BitIsClear(registers, n)) {
4285       if (!success)
4286         return false;
4287 
4288       offset = (addr_byte_size * BitCount(registers)) * -1;
4289       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4290       context.SetImmediateSigned(offset);
4291       addr_t addr = Rn + offset;
4292       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4293                                  addr))
4294         return false;
4295     }
4296 
4297     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4298     // possible for encoding A1
4299     if (wback && BitIsSet(registers, n))
4300       return WriteBits32Unknown(n);
4301   }
4302   return true;
4303 }
4304 
4305 // LDMIB loads multiple registers from consecutive memory locations using an
4306 // address from a base register.  The
4307 // consecutive memory locations start just above this address, and thea ddress
4308 // of the last of those locations can optinoally be written back to the base
4309 // register.
EmulateLDMIB(const uint32_t opcode,const ARMEncoding encoding)4310 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4311                                          const ARMEncoding encoding) {
4312 #if 0
4313     if ConditionPassed() then
4314         EncodingSpecificOperations();
4315         address = R[n] + 4;
4316 
4317         for i = 0 to 14
4318             if registers<i> == '1' then
4319                   R[i] = MemA[address,4]; address = address + 4;
4320         if registers<15> == '1' then
4321             LoadWritePC(MemA[address,4]);
4322 
4323         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4324         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4325 #endif
4326 
4327   bool success = false;
4328 
4329   if (ConditionPassed(opcode)) {
4330     uint32_t n;
4331     uint32_t registers = 0;
4332     bool wback;
4333     const uint32_t addr_byte_size = GetAddressByteSize();
4334     switch (encoding) {
4335     case eEncodingA1:
4336       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4337       n = Bits32(opcode, 19, 16);
4338       registers = Bits32(opcode, 15, 0);
4339       wback = BitIsSet(opcode, 21);
4340 
4341       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4342       if ((n == 15) || (BitCount(registers) < 1))
4343         return false;
4344 
4345       break;
4346     default:
4347       return false;
4348     }
4349     // address = R[n] + 4;
4350 
4351     int32_t offset = 0;
4352     addr_t Rn =
4353         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4354 
4355     if (!success)
4356       return false;
4357 
4358     addr_t address = Rn + addr_byte_size;
4359 
4360     EmulateInstruction::Context context;
4361     context.type = EmulateInstruction::eContextRegisterPlusOffset;
4362     RegisterInfo dwarf_reg;
4363     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4364     context.SetRegisterPlusOffset(dwarf_reg, offset);
4365 
4366     for (int i = 0; i < 14; ++i) {
4367       if (BitIsSet(registers, i)) {
4368         // R[i] = MemA[address,4]; address = address + 4;
4369 
4370         context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4371         uint32_t data =
4372             MemARead(context, address + offset, addr_byte_size, 0, &success);
4373         if (!success)
4374           return false;
4375 
4376         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4377                                    data))
4378           return false;
4379 
4380         offset += addr_byte_size;
4381       }
4382     }
4383 
4384     // if registers<15> == '1' then
4385     //     LoadWritePC(MemA[address,4]);
4386     if (BitIsSet(registers, 15)) {
4387       context.SetRegisterPlusOffset(dwarf_reg, offset);
4388       uint32_t data =
4389           MemARead(context, address + offset, addr_byte_size, 0, &success);
4390       if (!success)
4391         return false;
4392       // In ARMv5T and above, this is an interworking branch.
4393       if (!LoadWritePC(context, data))
4394         return false;
4395     }
4396 
4397     // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4398     if (wback && BitIsClear(registers, n)) {
4399       if (!success)
4400         return false;
4401 
4402       offset = addr_byte_size * BitCount(registers);
4403       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4404       context.SetImmediateSigned(offset);
4405       addr_t addr = Rn + offset;
4406       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4407                                  addr))
4408         return false;
4409     }
4410 
4411     // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4412     // possible for encoding A1
4413     if (wback && BitIsSet(registers, n))
4414       return WriteBits32Unknown(n);
4415   }
4416   return true;
4417 }
4418 
4419 // Load Register (immediate) calculates an address from a base register value
4420 // and an immediate offset, loads a word from memory, and writes to a register.
4421 // LDR (immediate, Thumb)
EmulateLDRRtRnImm(const uint32_t opcode,const ARMEncoding encoding)4422 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4423                                               const ARMEncoding encoding) {
4424 #if 0
4425     // ARM pseudo code...
4426     if (ConditionPassed())
4427     {
4428         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4429         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4430         address = if index then offset_addr else R[n];
4431         data = MemU[address,4];
4432         if wback then R[n] = offset_addr;
4433         if t == 15 then
4434             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4435         elsif UnalignedSupport() || address<1:0> = '00' then
4436             R[t] = data;
4437         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4438     }
4439 #endif
4440 
4441   bool success = false;
4442 
4443   if (ConditionPassed(opcode)) {
4444     uint32_t Rt;        // the destination register
4445     uint32_t Rn;        // the base register
4446     uint32_t imm32;     // the immediate offset used to form the address
4447     addr_t offset_addr; // the offset address
4448     addr_t address;     // the calculated address
4449     uint32_t data;      // the literal data value from memory load
4450     bool add, index, wback;
4451     switch (encoding) {
4452     case eEncodingT1:
4453       Rt = Bits32(opcode, 2, 0);
4454       Rn = Bits32(opcode, 5, 3);
4455       imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4456       // index = TRUE; add = TRUE; wback = FALSE
4457       add = true;
4458       index = true;
4459       wback = false;
4460 
4461       break;
4462 
4463     case eEncodingT2:
4464       // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4465       Rt = Bits32(opcode, 10, 8);
4466       Rn = 13;
4467       imm32 = Bits32(opcode, 7, 0) << 2;
4468 
4469       // index = TRUE; add = TRUE; wback = FALSE;
4470       index = true;
4471       add = true;
4472       wback = false;
4473 
4474       break;
4475 
4476     case eEncodingT3:
4477       // if Rn == '1111' then SEE LDR (literal);
4478       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4479       Rt = Bits32(opcode, 15, 12);
4480       Rn = Bits32(opcode, 19, 16);
4481       imm32 = Bits32(opcode, 11, 0);
4482 
4483       // index = TRUE; add = TRUE; wback = FALSE;
4484       index = true;
4485       add = true;
4486       wback = false;
4487 
4488       // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4489       if ((Rt == 15) && InITBlock() && !LastInITBlock())
4490         return false;
4491 
4492       break;
4493 
4494     case eEncodingT4:
4495       // if Rn == '1111' then SEE LDR (literal);
4496       // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4497       // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4498       // '00000100' then SEE POP;
4499       // if P == '0' && W == '0' then UNDEFINED;
4500       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4501         return false;
4502 
4503       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4504       Rt = Bits32(opcode, 15, 12);
4505       Rn = Bits32(opcode, 19, 16);
4506       imm32 = Bits32(opcode, 7, 0);
4507 
4508       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4509       index = BitIsSet(opcode, 10);
4510       add = BitIsSet(opcode, 9);
4511       wback = BitIsSet(opcode, 8);
4512 
4513       // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4514       // then UNPREDICTABLE;
4515       if ((wback && (Rn == Rt)) ||
4516           ((Rt == 15) && InITBlock() && !LastInITBlock()))
4517         return false;
4518 
4519       break;
4520 
4521     default:
4522       return false;
4523     }
4524     uint32_t base = ReadCoreReg(Rn, &success);
4525     if (!success)
4526       return false;
4527     if (add)
4528       offset_addr = base + imm32;
4529     else
4530       offset_addr = base - imm32;
4531 
4532     address = (index ? offset_addr : base);
4533 
4534     RegisterInfo base_reg;
4535     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4536     if (wback) {
4537       EmulateInstruction::Context ctx;
4538       if (Rn == 13) {
4539         ctx.type = eContextAdjustStackPointer;
4540         ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4541       } else if (Rn == GetFramePointerRegisterNumber()) {
4542         ctx.type = eContextSetFramePointer;
4543         ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4544       } else {
4545         ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4546         ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4547       }
4548 
4549       if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4550                                  offset_addr))
4551         return false;
4552     }
4553 
4554     // Prepare to write to the Rt register.
4555     EmulateInstruction::Context context;
4556     context.type = EmulateInstruction::eContextRegisterLoad;
4557     context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4558 
4559     // Read memory from the address.
4560     data = MemURead(context, address, 4, 0, &success);
4561     if (!success)
4562       return false;
4563 
4564     if (Rt == 15) {
4565       if (Bits32(address, 1, 0) == 0) {
4566         if (!LoadWritePC(context, data))
4567           return false;
4568       } else
4569         return false;
4570     } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4571       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4572                                  data))
4573         return false;
4574     } else
4575       WriteBits32Unknown(Rt);
4576   }
4577   return true;
4578 }
4579 
4580 // STM (Store Multiple Increment After) stores multiple registers to consecutive
4581 // memory locations using an address
4582 // from a base register.  The consecutive memory locations start at this
4583 // address, and the address just above the last of those locations can
4584 // optionally be written back to the base register.
EmulateSTM(const uint32_t opcode,const ARMEncoding encoding)4585 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4586                                        const ARMEncoding encoding) {
4587 #if 0
4588     if ConditionPassed() then
4589         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4590         address = R[n];
4591 
4592         for i = 0 to 14
4593             if registers<i> == '1' then
4594                 if i == n && wback && i != LowestSetBit(registers) then
4595                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4596                 else
4597                     MemA[address,4] = R[i];
4598                 address = address + 4;
4599 
4600         if registers<15> == '1' then // Only possible for encoding A1
4601             MemA[address,4] = PCStoreValue();
4602         if wback then R[n] = R[n] + 4*BitCount(registers);
4603 #endif
4604 
4605   bool success = false;
4606 
4607   if (ConditionPassed(opcode)) {
4608     uint32_t n;
4609     uint32_t registers = 0;
4610     bool wback;
4611     const uint32_t addr_byte_size = GetAddressByteSize();
4612 
4613     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4614     switch (encoding) {
4615     case eEncodingT1:
4616       // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4617       n = Bits32(opcode, 10, 8);
4618       registers = Bits32(opcode, 7, 0);
4619       registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4620       wback = true;
4621 
4622       // if BitCount(registers) < 1 then UNPREDICTABLE;
4623       if (BitCount(registers) < 1)
4624         return false;
4625 
4626       break;
4627 
4628     case eEncodingT2:
4629       // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4630       n = Bits32(opcode, 19, 16);
4631       registers = Bits32(opcode, 15, 0);
4632       registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4633       wback = BitIsSet(opcode, 21);
4634 
4635       // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4636       if ((n == 15) || (BitCount(registers) < 2))
4637         return false;
4638 
4639       // if wback && registers<n> == '1' then UNPREDICTABLE;
4640       if (wback && BitIsSet(registers, n))
4641         return false;
4642 
4643       break;
4644 
4645     case eEncodingA1:
4646       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4647       n = Bits32(opcode, 19, 16);
4648       registers = Bits32(opcode, 15, 0);
4649       wback = BitIsSet(opcode, 21);
4650 
4651       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4652       if ((n == 15) || (BitCount(registers) < 1))
4653         return false;
4654 
4655       break;
4656 
4657     default:
4658       return false;
4659     }
4660 
4661     // address = R[n];
4662     int32_t offset = 0;
4663     const addr_t address =
4664         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4665     if (!success)
4666       return false;
4667 
4668     EmulateInstruction::Context context;
4669     context.type = EmulateInstruction::eContextRegisterStore;
4670     RegisterInfo base_reg;
4671     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4672 
4673     // for i = 0 to 14
4674     uint32_t lowest_set_bit = 14;
4675     for (uint32_t i = 0; i < 14; ++i) {
4676       // if registers<i> == '1' then
4677       if (BitIsSet(registers, i)) {
4678         if (i < lowest_set_bit)
4679           lowest_set_bit = i;
4680         // if i == n && wback && i != LowestSetBit(registers) then
4681         if ((i == n) && wback && (i != lowest_set_bit))
4682           // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4683           // T1 and A1
4684           WriteBits32UnknownToMemory(address + offset);
4685         else {
4686           // MemA[address,4] = R[i];
4687           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4688                                                0, &success);
4689           if (!success)
4690             return false;
4691 
4692           RegisterInfo data_reg;
4693           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4694           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4695           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4696             return false;
4697         }
4698 
4699         // address = address + 4;
4700         offset += addr_byte_size;
4701       }
4702     }
4703 
4704     // if registers<15> == '1' then // Only possible for encoding A1
4705     //     MemA[address,4] = PCStoreValue();
4706     if (BitIsSet(registers, 15)) {
4707       RegisterInfo pc_reg;
4708       GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4709       context.SetRegisterPlusOffset(pc_reg, 8);
4710       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4711       if (!success)
4712         return false;
4713 
4714       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4715         return false;
4716     }
4717 
4718     // if wback then R[n] = R[n] + 4*BitCount(registers);
4719     if (wback) {
4720       offset = addr_byte_size * BitCount(registers);
4721       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4722       context.SetImmediateSigned(offset);
4723       addr_t data = address + offset;
4724       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4725                                  data))
4726         return false;
4727     }
4728   }
4729   return true;
4730 }
4731 
4732 // STMDA (Store Multiple Decrement After) stores multiple registers to
4733 // consecutive memory locations using an address from a base register.  The
4734 // consecutive memory locations end at this address, and the address just below
4735 // the lowest of those locations can optionally be written back to the base
4736 // register.
EmulateSTMDA(const uint32_t opcode,const ARMEncoding encoding)4737 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4738                                          const ARMEncoding encoding) {
4739 #if 0
4740     if ConditionPassed() then
4741         EncodingSpecificOperations();
4742         address = R[n] - 4*BitCount(registers) + 4;
4743 
4744         for i = 0 to 14
4745             if registers<i> == '1' then
4746                 if i == n && wback && i != LowestSetBit(registers) then
4747                     MemA[address,4] = bits(32) UNKNOWN;
4748                 else
4749                     MemA[address,4] = R[i];
4750                 address = address + 4;
4751 
4752         if registers<15> == '1' then
4753             MemA[address,4] = PCStoreValue();
4754 
4755         if wback then R[n] = R[n] - 4*BitCount(registers);
4756 #endif
4757 
4758   bool success = false;
4759 
4760   if (ConditionPassed(opcode)) {
4761     uint32_t n;
4762     uint32_t registers = 0;
4763     bool wback;
4764     const uint32_t addr_byte_size = GetAddressByteSize();
4765 
4766     // EncodingSpecificOperations();
4767     switch (encoding) {
4768     case eEncodingA1:
4769       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4770       n = Bits32(opcode, 19, 16);
4771       registers = Bits32(opcode, 15, 0);
4772       wback = BitIsSet(opcode, 21);
4773 
4774       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4775       if ((n == 15) || (BitCount(registers) < 1))
4776         return false;
4777       break;
4778     default:
4779       return false;
4780     }
4781 
4782     // address = R[n] - 4*BitCount(registers) + 4;
4783     int32_t offset = 0;
4784     addr_t Rn = ReadCoreReg(n, &success);
4785     if (!success)
4786       return false;
4787 
4788     addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4789 
4790     EmulateInstruction::Context context;
4791     context.type = EmulateInstruction::eContextRegisterStore;
4792     RegisterInfo base_reg;
4793     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4794 
4795     // for i = 0 to 14
4796     uint32_t lowest_bit_set = 14;
4797     for (uint32_t i = 0; i < 14; ++i) {
4798       // if registers<i> == '1' then
4799       if (BitIsSet(registers, i)) {
4800         if (i < lowest_bit_set)
4801           lowest_bit_set = i;
4802         // if i == n && wback && i != LowestSetBit(registers) then
4803         if ((i == n) && wback && (i != lowest_bit_set))
4804           // MemA[address,4] = bits(32) UNKNOWN;
4805           WriteBits32UnknownToMemory(address + offset);
4806         else {
4807           // MemA[address,4] = R[i];
4808           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4809                                                0, &success);
4810           if (!success)
4811             return false;
4812 
4813           RegisterInfo data_reg;
4814           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4815           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4816                                                   Rn - (address + offset));
4817           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4818             return false;
4819         }
4820 
4821         // address = address + 4;
4822         offset += addr_byte_size;
4823       }
4824     }
4825 
4826     // if registers<15> == '1' then
4827     //    MemA[address,4] = PCStoreValue();
4828     if (BitIsSet(registers, 15)) {
4829       RegisterInfo pc_reg;
4830       GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4831       context.SetRegisterPlusOffset(pc_reg, 8);
4832       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4833       if (!success)
4834         return false;
4835 
4836       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4837         return false;
4838     }
4839 
4840     // if wback then R[n] = R[n] - 4*BitCount(registers);
4841     if (wback) {
4842       offset = (addr_byte_size * BitCount(registers)) * -1;
4843       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4844       context.SetImmediateSigned(offset);
4845       addr_t data = Rn + offset;
4846       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4847                                  data))
4848         return false;
4849     }
4850   }
4851   return true;
4852 }
4853 
4854 // STMDB (Store Multiple Decrement Before) stores multiple registers to
4855 // consecutive memory locations using an address from a base register.  The
4856 // consecutive memory locations end just below this address, and the address of
4857 // the first of those locations can optionally be written back to the base
4858 // register.
EmulateSTMDB(const uint32_t opcode,const ARMEncoding encoding)4859 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4860                                          const ARMEncoding encoding) {
4861 #if 0
4862     if ConditionPassed() then
4863         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4864         address = R[n] - 4*BitCount(registers);
4865 
4866         for i = 0 to 14
4867             if registers<i> == '1' then
4868                 if i == n && wback && i != LowestSetBit(registers) then
4869                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4870                 else
4871                     MemA[address,4] = R[i];
4872                 address = address + 4;
4873 
4874         if registers<15> == '1' then // Only possible for encoding A1
4875             MemA[address,4] = PCStoreValue();
4876 
4877         if wback then R[n] = R[n] - 4*BitCount(registers);
4878 #endif
4879 
4880   bool success = false;
4881 
4882   if (ConditionPassed(opcode)) {
4883     uint32_t n;
4884     uint32_t registers = 0;
4885     bool wback;
4886     const uint32_t addr_byte_size = GetAddressByteSize();
4887 
4888     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4889     switch (encoding) {
4890     case eEncodingT1:
4891       // if W == '1' && Rn == '1101' then SEE PUSH;
4892       if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4893         // See PUSH
4894       }
4895       // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4896       n = Bits32(opcode, 19, 16);
4897       registers = Bits32(opcode, 15, 0);
4898       registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4899       wback = BitIsSet(opcode, 21);
4900       // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4901       if ((n == 15) || BitCount(registers) < 2)
4902         return false;
4903       // if wback && registers<n> == '1' then UNPREDICTABLE;
4904       if (wback && BitIsSet(registers, n))
4905         return false;
4906       break;
4907 
4908     case eEncodingA1:
4909       // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4910       // PUSH;
4911       if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4912           BitCount(Bits32(opcode, 15, 0)) >= 2) {
4913         // See Push
4914       }
4915       // n = UInt(Rn); registers = register_list; wback = (W == '1');
4916       n = Bits32(opcode, 19, 16);
4917       registers = Bits32(opcode, 15, 0);
4918       wback = BitIsSet(opcode, 21);
4919       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4920       if ((n == 15) || BitCount(registers) < 1)
4921         return false;
4922       break;
4923 
4924     default:
4925       return false;
4926     }
4927 
4928     // address = R[n] - 4*BitCount(registers);
4929 
4930     int32_t offset = 0;
4931     addr_t Rn =
4932         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4933     if (!success)
4934       return false;
4935 
4936     addr_t address = Rn - (addr_byte_size * BitCount(registers));
4937 
4938     EmulateInstruction::Context context;
4939     context.type = EmulateInstruction::eContextRegisterStore;
4940     RegisterInfo base_reg;
4941     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4942 
4943     // for i = 0 to 14
4944     uint32_t lowest_set_bit = 14;
4945     for (uint32_t i = 0; i < 14; ++i) {
4946       // if registers<i> == '1' then
4947       if (BitIsSet(registers, i)) {
4948         if (i < lowest_set_bit)
4949           lowest_set_bit = i;
4950         // if i == n && wback && i != LowestSetBit(registers) then
4951         if ((i == n) && wback && (i != lowest_set_bit))
4952           // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4953           // A1
4954           WriteBits32UnknownToMemory(address + offset);
4955         else {
4956           // MemA[address,4] = R[i];
4957           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4958                                                0, &success);
4959           if (!success)
4960             return false;
4961 
4962           RegisterInfo data_reg;
4963           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4964           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4965                                                   Rn - (address + offset));
4966           if (!MemAWrite(context, address + offset, data, addr_byte_size))
4967             return false;
4968         }
4969 
4970         // address = address + 4;
4971         offset += addr_byte_size;
4972       }
4973     }
4974 
4975     // if registers<15> == '1' then // Only possible for encoding A1
4976     //     MemA[address,4] = PCStoreValue();
4977     if (BitIsSet(registers, 15)) {
4978       RegisterInfo pc_reg;
4979       GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4980       context.SetRegisterPlusOffset(pc_reg, 8);
4981       const uint32_t pc = ReadCoreReg(PC_REG, &success);
4982       if (!success)
4983         return false;
4984 
4985       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4986         return false;
4987     }
4988 
4989     // if wback then R[n] = R[n] - 4*BitCount(registers);
4990     if (wback) {
4991       offset = (addr_byte_size * BitCount(registers)) * -1;
4992       context.type = EmulateInstruction::eContextAdjustBaseRegister;
4993       context.SetImmediateSigned(offset);
4994       addr_t data = Rn + offset;
4995       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4996                                  data))
4997         return false;
4998     }
4999   }
5000   return true;
5001 }
5002 
5003 // STMIB (Store Multiple Increment Before) stores multiple registers to
5004 // consecutive memory locations using an address from a base register.  The
5005 // consecutive memory locations start just above this address, and the address
5006 // of the last of those locations can optionally be written back to the base
5007 // register.
EmulateSTMIB(const uint32_t opcode,const ARMEncoding encoding)5008 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5009                                          const ARMEncoding encoding) {
5010 #if 0
5011     if ConditionPassed() then
5012         EncodingSpecificOperations();
5013         address = R[n] + 4;
5014 
5015         for i = 0 to 14
5016             if registers<i> == '1' then
5017                 if i == n && wback && i != LowestSetBit(registers) then
5018                     MemA[address,4] = bits(32) UNKNOWN;
5019                 else
5020                     MemA[address,4] = R[i];
5021                 address = address + 4;
5022 
5023         if registers<15> == '1' then
5024             MemA[address,4] = PCStoreValue();
5025 
5026         if wback then R[n] = R[n] + 4*BitCount(registers);
5027 #endif
5028 
5029   bool success = false;
5030 
5031   if (ConditionPassed(opcode)) {
5032     uint32_t n;
5033     uint32_t registers = 0;
5034     bool wback;
5035     const uint32_t addr_byte_size = GetAddressByteSize();
5036 
5037     // EncodingSpecificOperations();
5038     switch (encoding) {
5039     case eEncodingA1:
5040       // n = UInt(Rn); registers = register_list; wback = (W == '1');
5041       n = Bits32(opcode, 19, 16);
5042       registers = Bits32(opcode, 15, 0);
5043       wback = BitIsSet(opcode, 21);
5044 
5045       // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5046       if ((n == 15) && (BitCount(registers) < 1))
5047         return false;
5048       break;
5049     default:
5050       return false;
5051     }
5052     // address = R[n] + 4;
5053 
5054     int32_t offset = 0;
5055     addr_t Rn = ReadCoreReg(n, &success);
5056     if (!success)
5057       return false;
5058 
5059     addr_t address = Rn + addr_byte_size;
5060 
5061     EmulateInstruction::Context context;
5062     context.type = EmulateInstruction::eContextRegisterStore;
5063     RegisterInfo base_reg;
5064     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5065 
5066     uint32_t lowest_set_bit = 14;
5067     // for i = 0 to 14
5068     for (uint32_t i = 0; i < 14; ++i) {
5069       // if registers<i> == '1' then
5070       if (BitIsSet(registers, i)) {
5071         if (i < lowest_set_bit)
5072           lowest_set_bit = i;
5073         // if i == n && wback && i != LowestSetBit(registers) then
5074         if ((i == n) && wback && (i != lowest_set_bit))
5075           // MemA[address,4] = bits(32) UNKNOWN;
5076           WriteBits32UnknownToMemory(address + offset);
5077         // else
5078         else {
5079           // MemA[address,4] = R[i];
5080           uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5081                                                0, &success);
5082           if (!success)
5083             return false;
5084 
5085           RegisterInfo data_reg;
5086           GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5087           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5088                                                   offset + addr_byte_size);
5089           if (!MemAWrite(context, address + offset, data, addr_byte_size))
5090             return false;
5091         }
5092 
5093         // address = address + 4;
5094         offset += addr_byte_size;
5095       }
5096     }
5097 
5098     // if registers<15> == '1' then
5099     // MemA[address,4] = PCStoreValue();
5100     if (BitIsSet(registers, 15)) {
5101       RegisterInfo pc_reg;
5102       GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5103       context.SetRegisterPlusOffset(pc_reg, 8);
5104       const uint32_t pc = ReadCoreReg(PC_REG, &success);
5105       if (!success)
5106         return false;
5107 
5108       if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5109         return false;
5110     }
5111 
5112     // if wback then R[n] = R[n] + 4*BitCount(registers);
5113     if (wback) {
5114       offset = addr_byte_size * BitCount(registers);
5115       context.type = EmulateInstruction::eContextAdjustBaseRegister;
5116       context.SetImmediateSigned(offset);
5117       addr_t data = Rn + offset;
5118       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5119                                  data))
5120         return false;
5121     }
5122   }
5123   return true;
5124 }
5125 
5126 // STR (store immediate) calculates an address from a base register value and an
5127 // immediate offset, and stores a word
5128 // from a register to memory.  It can use offset, post-indexed, or pre-indexed
5129 // addressing.
EmulateSTRThumb(const uint32_t opcode,const ARMEncoding encoding)5130 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5131                                             const ARMEncoding encoding) {
5132 #if 0
5133     if ConditionPassed() then
5134         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5135         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5136         address = if index then offset_addr else R[n];
5137         if UnalignedSupport() || address<1:0> == '00' then
5138             MemU[address,4] = R[t];
5139         else // Can only occur before ARMv7
5140             MemU[address,4] = bits(32) UNKNOWN;
5141         if wback then R[n] = offset_addr;
5142 #endif
5143 
5144   bool success = false;
5145 
5146   if (ConditionPassed(opcode)) {
5147     const uint32_t addr_byte_size = GetAddressByteSize();
5148 
5149     uint32_t t;
5150     uint32_t n;
5151     uint32_t imm32;
5152     bool index;
5153     bool add;
5154     bool wback;
5155     // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5156     switch (encoding) {
5157     case eEncodingT1:
5158       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5159       t = Bits32(opcode, 2, 0);
5160       n = Bits32(opcode, 5, 3);
5161       imm32 = Bits32(opcode, 10, 6) << 2;
5162 
5163       // index = TRUE; add = TRUE; wback = FALSE;
5164       index = true;
5165       add = false;
5166       wback = false;
5167       break;
5168 
5169     case eEncodingT2:
5170       // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5171       t = Bits32(opcode, 10, 8);
5172       n = 13;
5173       imm32 = Bits32(opcode, 7, 0) << 2;
5174 
5175       // index = TRUE; add = TRUE; wback = FALSE;
5176       index = true;
5177       add = true;
5178       wback = false;
5179       break;
5180 
5181     case eEncodingT3:
5182       // if Rn == '1111' then UNDEFINED;
5183       if (Bits32(opcode, 19, 16) == 15)
5184         return false;
5185 
5186       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5187       t = Bits32(opcode, 15, 12);
5188       n = Bits32(opcode, 19, 16);
5189       imm32 = Bits32(opcode, 11, 0);
5190 
5191       // index = TRUE; add = TRUE; wback = FALSE;
5192       index = true;
5193       add = true;
5194       wback = false;
5195 
5196       // if t == 15 then UNPREDICTABLE;
5197       if (t == 15)
5198         return false;
5199       break;
5200 
5201     case eEncodingT4:
5202       // if P == '1' && U == '1' && W == '0' then SEE STRT;
5203       // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5204       // '00000100' then SEE PUSH;
5205       // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5206       if ((Bits32(opcode, 19, 16) == 15) ||
5207           (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5208         return false;
5209 
5210       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5211       t = Bits32(opcode, 15, 12);
5212       n = Bits32(opcode, 19, 16);
5213       imm32 = Bits32(opcode, 7, 0);
5214 
5215       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5216       index = BitIsSet(opcode, 10);
5217       add = BitIsSet(opcode, 9);
5218       wback = BitIsSet(opcode, 8);
5219 
5220       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5221       if ((t == 15) || (wback && (n == t)))
5222         return false;
5223       break;
5224 
5225     default:
5226       return false;
5227     }
5228 
5229     addr_t offset_addr;
5230     addr_t address;
5231 
5232     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5233     uint32_t base_address = ReadCoreReg(n, &success);
5234     if (!success)
5235       return false;
5236 
5237     if (add)
5238       offset_addr = base_address + imm32;
5239     else
5240       offset_addr = base_address - imm32;
5241 
5242     // address = if index then offset_addr else R[n];
5243     if (index)
5244       address = offset_addr;
5245     else
5246       address = base_address;
5247 
5248     EmulateInstruction::Context context;
5249     if (n == 13)
5250       context.type = eContextPushRegisterOnStack;
5251     else
5252       context.type = eContextRegisterStore;
5253 
5254     RegisterInfo base_reg;
5255     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5256 
5257     // if UnalignedSupport() || address<1:0> == '00' then
5258     if (UnalignedSupport() ||
5259         (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5260       // MemU[address,4] = R[t];
5261       uint32_t data =
5262           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5263       if (!success)
5264         return false;
5265 
5266       RegisterInfo data_reg;
5267       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5268       int32_t offset = address - base_address;
5269       context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5270       if (!MemUWrite(context, address, data, addr_byte_size))
5271         return false;
5272     } else {
5273       // MemU[address,4] = bits(32) UNKNOWN;
5274       WriteBits32UnknownToMemory(address);
5275     }
5276 
5277     // if wback then R[n] = offset_addr;
5278     if (wback) {
5279       if (n == 13)
5280         context.type = eContextAdjustStackPointer;
5281       else
5282         context.type = eContextAdjustBaseRegister;
5283       context.SetAddress(offset_addr);
5284 
5285       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5286                                  offset_addr))
5287         return false;
5288     }
5289   }
5290   return true;
5291 }
5292 
5293 // STR (Store Register) calculates an address from a base register value and an
5294 // offset register value, stores a
5295 // word from a register to memory.   The offset register value can optionally
5296 // be shifted.
EmulateSTRRegister(const uint32_t opcode,const ARMEncoding encoding)5297 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5298                                                const ARMEncoding encoding) {
5299 #if 0
5300     if ConditionPassed() then
5301         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5302         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5303         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5304         address = if index then offset_addr else R[n];
5305         if t == 15 then // Only possible for encoding A1
5306             data = PCStoreValue();
5307         else
5308             data = R[t];
5309         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5310             MemU[address,4] = data;
5311         else // Can only occur before ARMv7
5312             MemU[address,4] = bits(32) UNKNOWN;
5313         if wback then R[n] = offset_addr;
5314 #endif
5315 
5316   bool success = false;
5317 
5318   if (ConditionPassed(opcode)) {
5319     const uint32_t addr_byte_size = GetAddressByteSize();
5320 
5321     uint32_t t;
5322     uint32_t n;
5323     uint32_t m;
5324     ARM_ShifterType shift_t;
5325     uint32_t shift_n;
5326     bool index;
5327     bool add;
5328     bool wback;
5329 
5330     // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5331     switch (encoding) {
5332     case eEncodingT1:
5333       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5334       // in ThumbEE";
5335       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5336       t = Bits32(opcode, 2, 0);
5337       n = Bits32(opcode, 5, 3);
5338       m = Bits32(opcode, 8, 6);
5339 
5340       // index = TRUE; add = TRUE; wback = FALSE;
5341       index = true;
5342       add = true;
5343       wback = false;
5344 
5345       // (shift_t, shift_n) = (SRType_LSL, 0);
5346       shift_t = SRType_LSL;
5347       shift_n = 0;
5348       break;
5349 
5350     case eEncodingT2:
5351       // if Rn == '1111' then UNDEFINED;
5352       if (Bits32(opcode, 19, 16) == 15)
5353         return false;
5354 
5355       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5356       t = Bits32(opcode, 15, 12);
5357       n = Bits32(opcode, 19, 16);
5358       m = Bits32(opcode, 3, 0);
5359 
5360       // index = TRUE; add = TRUE; wback = FALSE;
5361       index = true;
5362       add = true;
5363       wback = false;
5364 
5365       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5366       shift_t = SRType_LSL;
5367       shift_n = Bits32(opcode, 5, 4);
5368 
5369       // if t == 15 || BadReg(m) then UNPREDICTABLE;
5370       if ((t == 15) || (BadReg(m)))
5371         return false;
5372       break;
5373 
5374     case eEncodingA1: {
5375       // if P == '0' && W == '1' then SEE STRT;
5376       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5377       t = Bits32(opcode, 15, 12);
5378       n = Bits32(opcode, 19, 16);
5379       m = Bits32(opcode, 3, 0);
5380 
5381       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5382       // (W == '1');
5383       index = BitIsSet(opcode, 24);
5384       add = BitIsSet(opcode, 23);
5385       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5386 
5387       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5388       uint32_t typ = Bits32(opcode, 6, 5);
5389       uint32_t imm5 = Bits32(opcode, 11, 7);
5390       shift_n = DecodeImmShift(typ, imm5, shift_t);
5391 
5392       // if m == 15 then UNPREDICTABLE;
5393       if (m == 15)
5394         return false;
5395 
5396       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5397       if (wback && ((n == 15) || (n == t)))
5398         return false;
5399 
5400       break;
5401     }
5402     default:
5403       return false;
5404     }
5405 
5406     addr_t offset_addr;
5407     addr_t address;
5408     int32_t offset = 0;
5409 
5410     addr_t base_address =
5411         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5412     if (!success)
5413       return false;
5414 
5415     uint32_t Rm_data =
5416         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5417     if (!success)
5418       return false;
5419 
5420     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5421     offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5422     if (!success)
5423       return false;
5424 
5425     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5426     if (add)
5427       offset_addr = base_address + offset;
5428     else
5429       offset_addr = base_address - offset;
5430 
5431     // address = if index then offset_addr else R[n];
5432     if (index)
5433       address = offset_addr;
5434     else
5435       address = base_address;
5436 
5437     uint32_t data;
5438     // if t == 15 then // Only possible for encoding A1
5439     if (t == 15)
5440       // data = PCStoreValue();
5441       data = ReadCoreReg(PC_REG, &success);
5442     else
5443       // data = R[t];
5444       data =
5445           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5446 
5447     if (!success)
5448       return false;
5449 
5450     EmulateInstruction::Context context;
5451     context.type = eContextRegisterStore;
5452 
5453     // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5454     // InstrSet_ARM then
5455     if (UnalignedSupport() ||
5456         (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5457         CurrentInstrSet() == eModeARM) {
5458       // MemU[address,4] = data;
5459 
5460       RegisterInfo base_reg;
5461       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5462 
5463       RegisterInfo data_reg;
5464       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5465 
5466       context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5467                                               address - base_address);
5468       if (!MemUWrite(context, address, data, addr_byte_size))
5469         return false;
5470 
5471     } else
5472       // MemU[address,4] = bits(32) UNKNOWN;
5473       WriteBits32UnknownToMemory(address);
5474 
5475     // if wback then R[n] = offset_addr;
5476     if (wback) {
5477       context.type = eContextRegisterLoad;
5478       context.SetAddress(offset_addr);
5479       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5480                                  offset_addr))
5481         return false;
5482     }
5483   }
5484   return true;
5485 }
5486 
EmulateSTRBThumb(const uint32_t opcode,const ARMEncoding encoding)5487 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5488                                              const ARMEncoding encoding) {
5489 #if 0
5490     if ConditionPassed() then
5491         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5492         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5493         address = if index then offset_addr else R[n];
5494         MemU[address,1] = R[t]<7:0>;
5495         if wback then R[n] = offset_addr;
5496 #endif
5497 
5498   bool success = false;
5499 
5500   if (ConditionPassed(opcode)) {
5501     uint32_t t;
5502     uint32_t n;
5503     uint32_t imm32;
5504     bool index;
5505     bool add;
5506     bool wback;
5507     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5508     switch (encoding) {
5509     case eEncodingT1:
5510       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5511       t = Bits32(opcode, 2, 0);
5512       n = Bits32(opcode, 5, 3);
5513       imm32 = Bits32(opcode, 10, 6);
5514 
5515       // index = TRUE; add = TRUE; wback = FALSE;
5516       index = true;
5517       add = true;
5518       wback = false;
5519       break;
5520 
5521     case eEncodingT2:
5522       // if Rn == '1111' then UNDEFINED;
5523       if (Bits32(opcode, 19, 16) == 15)
5524         return false;
5525 
5526       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5527       t = Bits32(opcode, 15, 12);
5528       n = Bits32(opcode, 19, 16);
5529       imm32 = Bits32(opcode, 11, 0);
5530 
5531       // index = TRUE; add = TRUE; wback = FALSE;
5532       index = true;
5533       add = true;
5534       wback = false;
5535 
5536       // if BadReg(t) then UNPREDICTABLE;
5537       if (BadReg(t))
5538         return false;
5539       break;
5540 
5541     case eEncodingT3:
5542       // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5543       // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5544       if (Bits32(opcode, 19, 16) == 15)
5545         return false;
5546 
5547       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5548       t = Bits32(opcode, 15, 12);
5549       n = Bits32(opcode, 19, 16);
5550       imm32 = Bits32(opcode, 7, 0);
5551 
5552       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5553       index = BitIsSet(opcode, 10);
5554       add = BitIsSet(opcode, 9);
5555       wback = BitIsSet(opcode, 8);
5556 
5557       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5558       if ((BadReg(t)) || (wback && (n == t)))
5559         return false;
5560       break;
5561 
5562     default:
5563       return false;
5564     }
5565 
5566     addr_t offset_addr;
5567     addr_t address;
5568     addr_t base_address =
5569         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5570     if (!success)
5571       return false;
5572 
5573     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5574     if (add)
5575       offset_addr = base_address + imm32;
5576     else
5577       offset_addr = base_address - imm32;
5578 
5579     // address = if index then offset_addr else R[n];
5580     if (index)
5581       address = offset_addr;
5582     else
5583       address = base_address;
5584 
5585     // MemU[address,1] = R[t]<7:0>
5586     RegisterInfo base_reg;
5587     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5588 
5589     RegisterInfo data_reg;
5590     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5591 
5592     EmulateInstruction::Context context;
5593     context.type = eContextRegisterStore;
5594     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5595                                             address - base_address);
5596 
5597     uint32_t data =
5598         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5599     if (!success)
5600       return false;
5601 
5602     data = Bits32(data, 7, 0);
5603 
5604     if (!MemUWrite(context, address, data, 1))
5605       return false;
5606 
5607     // if wback then R[n] = offset_addr;
5608     if (wback) {
5609       context.type = eContextRegisterLoad;
5610       context.SetAddress(offset_addr);
5611       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5612                                  offset_addr))
5613         return false;
5614     }
5615   }
5616 
5617   return true;
5618 }
5619 
5620 // STRH (register) calculates an address from a base register value and an
5621 // offset register value, and stores a
5622 // halfword from a register to memory.  The offset register value can be
5623 // shifted left by 0, 1, 2, or 3 bits.
EmulateSTRHRegister(const uint32_t opcode,const ARMEncoding encoding)5624 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5625                                                 const ARMEncoding encoding) {
5626 #if 0
5627     if ConditionPassed() then
5628         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5629         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5630         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5631         address = if index then offset_addr else R[n];
5632         if UnalignedSupport() || address<0> == '0' then
5633             MemU[address,2] = R[t]<15:0>;
5634         else // Can only occur before ARMv7
5635             MemU[address,2] = bits(16) UNKNOWN;
5636         if wback then R[n] = offset_addr;
5637 #endif
5638 
5639   bool success = false;
5640 
5641   if (ConditionPassed(opcode)) {
5642     uint32_t t;
5643     uint32_t n;
5644     uint32_t m;
5645     bool index;
5646     bool add;
5647     bool wback;
5648     ARM_ShifterType shift_t;
5649     uint32_t shift_n;
5650 
5651     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5652     switch (encoding) {
5653     case eEncodingT1:
5654       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5655       // in ThumbEE";
5656       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5657       t = Bits32(opcode, 2, 0);
5658       n = Bits32(opcode, 5, 3);
5659       m = Bits32(opcode, 8, 6);
5660 
5661       // index = TRUE; add = TRUE; wback = FALSE;
5662       index = true;
5663       add = true;
5664       wback = false;
5665 
5666       // (shift_t, shift_n) = (SRType_LSL, 0);
5667       shift_t = SRType_LSL;
5668       shift_n = 0;
5669 
5670       break;
5671 
5672     case eEncodingT2:
5673       // if Rn == '1111' then UNDEFINED;
5674       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5675       t = Bits32(opcode, 15, 12);
5676       n = Bits32(opcode, 19, 16);
5677       m = Bits32(opcode, 3, 0);
5678       if (n == 15)
5679         return false;
5680 
5681       // index = TRUE; add = TRUE; wback = FALSE;
5682       index = true;
5683       add = true;
5684       wback = false;
5685 
5686       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5687       shift_t = SRType_LSL;
5688       shift_n = Bits32(opcode, 5, 4);
5689 
5690       // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5691       if (BadReg(t) || BadReg(m))
5692         return false;
5693 
5694       break;
5695 
5696     case eEncodingA1:
5697       // if P == '0' && W == '1' then SEE STRHT;
5698       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5699       t = Bits32(opcode, 15, 12);
5700       n = Bits32(opcode, 19, 16);
5701       m = Bits32(opcode, 3, 0);
5702 
5703       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5704       // (W == '1');
5705       index = BitIsSet(opcode, 24);
5706       add = BitIsSet(opcode, 23);
5707       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5708 
5709       // (shift_t, shift_n) = (SRType_LSL, 0);
5710       shift_t = SRType_LSL;
5711       shift_n = 0;
5712 
5713       // if t == 15 || m == 15 then UNPREDICTABLE;
5714       if ((t == 15) || (m == 15))
5715         return false;
5716 
5717       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5718       if (wback && ((n == 15) || (n == t)))
5719         return false;
5720 
5721       break;
5722 
5723     default:
5724       return false;
5725     }
5726 
5727     uint32_t Rm = ReadCoreReg(m, &success);
5728     if (!success)
5729       return false;
5730 
5731     uint32_t Rn = ReadCoreReg(n, &success);
5732     if (!success)
5733       return false;
5734 
5735     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5736     uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5737     if (!success)
5738       return false;
5739 
5740     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5741     addr_t offset_addr;
5742     if (add)
5743       offset_addr = Rn + offset;
5744     else
5745       offset_addr = Rn - offset;
5746 
5747     // address = if index then offset_addr else R[n];
5748     addr_t address;
5749     if (index)
5750       address = offset_addr;
5751     else
5752       address = Rn;
5753 
5754     EmulateInstruction::Context context;
5755     context.type = eContextRegisterStore;
5756     RegisterInfo base_reg;
5757     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5758     RegisterInfo offset_reg;
5759     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5760 
5761     // if UnalignedSupport() || address<0> == '0' then
5762     if (UnalignedSupport() || BitIsClear(address, 0)) {
5763       // MemU[address,2] = R[t]<15:0>;
5764       uint32_t Rt = ReadCoreReg(t, &success);
5765       if (!success)
5766         return false;
5767 
5768       EmulateInstruction::Context context;
5769       context.type = eContextRegisterStore;
5770       RegisterInfo base_reg;
5771       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5772       RegisterInfo offset_reg;
5773       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5774       RegisterInfo data_reg;
5775       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5776       context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5777                                                       data_reg);
5778 
5779       if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5780         return false;
5781     } else // Can only occur before ARMv7
5782     {
5783       // MemU[address,2] = bits(16) UNKNOWN;
5784     }
5785 
5786     // if wback then R[n] = offset_addr;
5787     if (wback) {
5788       context.type = eContextAdjustBaseRegister;
5789       context.SetAddress(offset_addr);
5790       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5791                                  offset_addr))
5792         return false;
5793     }
5794   }
5795 
5796   return true;
5797 }
5798 
5799 // Add with Carry (immediate) adds an immediate value and the carry flag value
5800 // to a register value, and writes the result to the destination register.  It
5801 // can optionally update the condition flags based on the result.
EmulateADCImm(const uint32_t opcode,const ARMEncoding encoding)5802 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5803                                           const ARMEncoding encoding) {
5804 #if 0
5805     // ARM pseudo code...
5806     if ConditionPassed() then
5807         EncodingSpecificOperations();
5808         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5809         if d == 15 then         // Can only occur for ARM encoding
5810             ALUWritePC(result); // setflags is always FALSE here
5811         else
5812             R[d] = result;
5813             if setflags then
5814                 APSR.N = result<31>;
5815                 APSR.Z = IsZeroBit(result);
5816                 APSR.C = carry;
5817                 APSR.V = overflow;
5818 #endif
5819 
5820   bool success = false;
5821 
5822   if (ConditionPassed(opcode)) {
5823     uint32_t Rd, Rn;
5824     uint32_t
5825         imm32; // the immediate value to be added to the value obtained from Rn
5826     bool setflags;
5827     switch (encoding) {
5828     case eEncodingT1:
5829       Rd = Bits32(opcode, 11, 8);
5830       Rn = Bits32(opcode, 19, 16);
5831       setflags = BitIsSet(opcode, 20);
5832       imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5833       if (BadReg(Rd) || BadReg(Rn))
5834         return false;
5835       break;
5836     case eEncodingA1:
5837       Rd = Bits32(opcode, 15, 12);
5838       Rn = Bits32(opcode, 19, 16);
5839       setflags = BitIsSet(opcode, 20);
5840       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5841 
5842       if (Rd == 15 && setflags)
5843         return EmulateSUBSPcLrEtc(opcode, encoding);
5844       break;
5845     default:
5846       return false;
5847     }
5848 
5849     // Read the first operand.
5850     int32_t val1 = ReadCoreReg(Rn, &success);
5851     if (!success)
5852       return false;
5853 
5854     AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5855 
5856     EmulateInstruction::Context context;
5857     context.type = EmulateInstruction::eContextImmediate;
5858     context.SetNoArgs();
5859 
5860     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5861                                    res.carry_out, res.overflow))
5862       return false;
5863   }
5864   return true;
5865 }
5866 
5867 // Add with Carry (register) adds a register value, the carry flag value, and
5868 // an optionally-shifted register value, and writes the result to the
5869 // destination register.  It can optionally update the condition flags based on
5870 // the result.
EmulateADCReg(const uint32_t opcode,const ARMEncoding encoding)5871 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5872                                           const ARMEncoding encoding) {
5873 #if 0
5874     // ARM pseudo code...
5875     if ConditionPassed() then
5876         EncodingSpecificOperations();
5877         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5878         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5879         if d == 15 then         // Can only occur for ARM encoding
5880             ALUWritePC(result); // setflags is always FALSE here
5881         else
5882             R[d] = result;
5883             if setflags then
5884                 APSR.N = result<31>;
5885                 APSR.Z = IsZeroBit(result);
5886                 APSR.C = carry;
5887                 APSR.V = overflow;
5888 #endif
5889 
5890   bool success = false;
5891 
5892   if (ConditionPassed(opcode)) {
5893     uint32_t Rd, Rn, Rm;
5894     ARM_ShifterType shift_t;
5895     uint32_t shift_n; // the shift applied to the value read from Rm
5896     bool setflags;
5897     switch (encoding) {
5898     case eEncodingT1:
5899       Rd = Rn = Bits32(opcode, 2, 0);
5900       Rm = Bits32(opcode, 5, 3);
5901       setflags = !InITBlock();
5902       shift_t = SRType_LSL;
5903       shift_n = 0;
5904       break;
5905     case eEncodingT2:
5906       Rd = Bits32(opcode, 11, 8);
5907       Rn = Bits32(opcode, 19, 16);
5908       Rm = Bits32(opcode, 3, 0);
5909       setflags = BitIsSet(opcode, 20);
5910       shift_n = DecodeImmShiftThumb(opcode, shift_t);
5911       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5912         return false;
5913       break;
5914     case eEncodingA1:
5915       Rd = Bits32(opcode, 15, 12);
5916       Rn = Bits32(opcode, 19, 16);
5917       Rm = Bits32(opcode, 3, 0);
5918       setflags = BitIsSet(opcode, 20);
5919       shift_n = DecodeImmShiftARM(opcode, shift_t);
5920 
5921       if (Rd == 15 && setflags)
5922         return EmulateSUBSPcLrEtc(opcode, encoding);
5923       break;
5924     default:
5925       return false;
5926     }
5927 
5928     // Read the first operand.
5929     int32_t val1 = ReadCoreReg(Rn, &success);
5930     if (!success)
5931       return false;
5932 
5933     // Read the second operand.
5934     int32_t val2 = ReadCoreReg(Rm, &success);
5935     if (!success)
5936       return false;
5937 
5938     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5939     if (!success)
5940       return false;
5941     AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5942 
5943     EmulateInstruction::Context context;
5944     context.type = EmulateInstruction::eContextImmediate;
5945     context.SetNoArgs();
5946 
5947     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5948                                    res.carry_out, res.overflow))
5949       return false;
5950   }
5951   return true;
5952 }
5953 
5954 // This instruction adds an immediate value to the PC value to form a PC-
5955 // relative address, and writes the result to the destination register.
EmulateADR(const uint32_t opcode,const ARMEncoding encoding)5956 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5957                                        const ARMEncoding encoding) {
5958 #if 0
5959     // ARM pseudo code...
5960     if ConditionPassed() then
5961         EncodingSpecificOperations();
5962         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5963         if d == 15 then         // Can only occur for ARM encodings
5964             ALUWritePC(result);
5965         else
5966             R[d] = result;
5967 #endif
5968 
5969   bool success = false;
5970 
5971   if (ConditionPassed(opcode)) {
5972     uint32_t Rd;
5973     uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5974     bool add;
5975     switch (encoding) {
5976     case eEncodingT1:
5977       Rd = Bits32(opcode, 10, 8);
5978       imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5979       add = true;
5980       break;
5981     case eEncodingT2:
5982     case eEncodingT3:
5983       Rd = Bits32(opcode, 11, 8);
5984       imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5985       add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5986       if (BadReg(Rd))
5987         return false;
5988       break;
5989     case eEncodingA1:
5990     case eEncodingA2:
5991       Rd = Bits32(opcode, 15, 12);
5992       imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
5993       add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5994       break;
5995     default:
5996       return false;
5997     }
5998 
5999     // Read the PC value.
6000     uint32_t pc = ReadCoreReg(PC_REG, &success);
6001     if (!success)
6002       return false;
6003 
6004     uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6005 
6006     EmulateInstruction::Context context;
6007     context.type = EmulateInstruction::eContextImmediate;
6008     context.SetNoArgs();
6009 
6010     if (!WriteCoreReg(context, result, Rd))
6011       return false;
6012   }
6013   return true;
6014 }
6015 
6016 // This instruction performs a bitwise AND of a register value and an immediate
6017 // value, and writes the result to the destination register.  It can optionally
6018 // update the condition flags based on the result.
EmulateANDImm(const uint32_t opcode,const ARMEncoding encoding)6019 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6020                                           const ARMEncoding encoding) {
6021 #if 0
6022     // ARM pseudo code...
6023     if ConditionPassed() then
6024         EncodingSpecificOperations();
6025         result = R[n] AND imm32;
6026         if d == 15 then         // Can only occur for ARM encoding
6027             ALUWritePC(result); // setflags is always FALSE here
6028         else
6029             R[d] = result;
6030             if setflags then
6031                 APSR.N = result<31>;
6032                 APSR.Z = IsZeroBit(result);
6033                 APSR.C = carry;
6034                 // APSR.V unchanged
6035 #endif
6036 
6037   bool success = false;
6038 
6039   if (ConditionPassed(opcode)) {
6040     uint32_t Rd, Rn;
6041     uint32_t
6042         imm32; // the immediate value to be ANDed to the value obtained from Rn
6043     bool setflags;
6044     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6045     switch (encoding) {
6046     case eEncodingT1:
6047       Rd = Bits32(opcode, 11, 8);
6048       Rn = Bits32(opcode, 19, 16);
6049       setflags = BitIsSet(opcode, 20);
6050       imm32 = ThumbExpandImm_C(
6051           opcode, APSR_C,
6052           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6053       // if Rd == '1111' && S == '1' then SEE TST (immediate);
6054       if (Rd == 15 && setflags)
6055         return EmulateTSTImm(opcode, eEncodingT1);
6056       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6057         return false;
6058       break;
6059     case eEncodingA1:
6060       Rd = Bits32(opcode, 15, 12);
6061       Rn = Bits32(opcode, 19, 16);
6062       setflags = BitIsSet(opcode, 20);
6063       imm32 =
6064           ARMExpandImm_C(opcode, APSR_C,
6065                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6066 
6067       if (Rd == 15 && setflags)
6068         return EmulateSUBSPcLrEtc(opcode, encoding);
6069       break;
6070     default:
6071       return false;
6072     }
6073 
6074     // Read the first operand.
6075     uint32_t val1 = ReadCoreReg(Rn, &success);
6076     if (!success)
6077       return false;
6078 
6079     uint32_t result = val1 & imm32;
6080 
6081     EmulateInstruction::Context context;
6082     context.type = EmulateInstruction::eContextImmediate;
6083     context.SetNoArgs();
6084 
6085     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6086       return false;
6087   }
6088   return true;
6089 }
6090 
6091 // This instruction performs a bitwise AND of a register value and an
6092 // optionally-shifted register value, and writes the result to the destination
6093 // register.  It can optionally update the condition flags based on the result.
EmulateANDReg(const uint32_t opcode,const ARMEncoding encoding)6094 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6095                                           const ARMEncoding encoding) {
6096 #if 0
6097     // ARM pseudo code...
6098     if ConditionPassed() then
6099         EncodingSpecificOperations();
6100         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6101         result = R[n] AND shifted;
6102         if d == 15 then         // Can only occur for ARM encoding
6103             ALUWritePC(result); // setflags is always FALSE here
6104         else
6105             R[d] = result;
6106             if setflags then
6107                 APSR.N = result<31>;
6108                 APSR.Z = IsZeroBit(result);
6109                 APSR.C = carry;
6110                 // APSR.V unchanged
6111 #endif
6112 
6113   bool success = false;
6114 
6115   if (ConditionPassed(opcode)) {
6116     uint32_t Rd, Rn, Rm;
6117     ARM_ShifterType shift_t;
6118     uint32_t shift_n; // the shift applied to the value read from Rm
6119     bool setflags;
6120     uint32_t carry;
6121     switch (encoding) {
6122     case eEncodingT1:
6123       Rd = Rn = Bits32(opcode, 2, 0);
6124       Rm = Bits32(opcode, 5, 3);
6125       setflags = !InITBlock();
6126       shift_t = SRType_LSL;
6127       shift_n = 0;
6128       break;
6129     case eEncodingT2:
6130       Rd = Bits32(opcode, 11, 8);
6131       Rn = Bits32(opcode, 19, 16);
6132       Rm = Bits32(opcode, 3, 0);
6133       setflags = BitIsSet(opcode, 20);
6134       shift_n = DecodeImmShiftThumb(opcode, shift_t);
6135       // if Rd == '1111' && S == '1' then SEE TST (register);
6136       if (Rd == 15 && setflags)
6137         return EmulateTSTReg(opcode, eEncodingT2);
6138       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6139         return false;
6140       break;
6141     case eEncodingA1:
6142       Rd = Bits32(opcode, 15, 12);
6143       Rn = Bits32(opcode, 19, 16);
6144       Rm = Bits32(opcode, 3, 0);
6145       setflags = BitIsSet(opcode, 20);
6146       shift_n = DecodeImmShiftARM(opcode, shift_t);
6147 
6148       if (Rd == 15 && setflags)
6149         return EmulateSUBSPcLrEtc(opcode, encoding);
6150       break;
6151     default:
6152       return false;
6153     }
6154 
6155     // Read the first operand.
6156     uint32_t val1 = ReadCoreReg(Rn, &success);
6157     if (!success)
6158       return false;
6159 
6160     // Read the second operand.
6161     uint32_t val2 = ReadCoreReg(Rm, &success);
6162     if (!success)
6163       return false;
6164 
6165     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6166     if (!success)
6167       return false;
6168     uint32_t result = val1 & shifted;
6169 
6170     EmulateInstruction::Context context;
6171     context.type = EmulateInstruction::eContextImmediate;
6172     context.SetNoArgs();
6173 
6174     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6175       return false;
6176   }
6177   return true;
6178 }
6179 
6180 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6181 // the complement of an immediate value, and writes the result to the
6182 // destination register.  It can optionally update the condition flags based on
6183 // the result.
EmulateBICImm(const uint32_t opcode,const ARMEncoding encoding)6184 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6185                                           const ARMEncoding encoding) {
6186 #if 0
6187     // ARM pseudo code...
6188     if ConditionPassed() then
6189         EncodingSpecificOperations();
6190         result = R[n] AND NOT(imm32);
6191         if d == 15 then         // Can only occur for ARM encoding
6192             ALUWritePC(result); // setflags is always FALSE here
6193         else
6194             R[d] = result;
6195             if setflags then
6196                 APSR.N = result<31>;
6197                 APSR.Z = IsZeroBit(result);
6198                 APSR.C = carry;
6199                 // APSR.V unchanged
6200 #endif
6201 
6202   bool success = false;
6203 
6204   if (ConditionPassed(opcode)) {
6205     uint32_t Rd, Rn;
6206     uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6207                     // the value obtained from Rn
6208     bool setflags;
6209     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6210     switch (encoding) {
6211     case eEncodingT1:
6212       Rd = Bits32(opcode, 11, 8);
6213       Rn = Bits32(opcode, 19, 16);
6214       setflags = BitIsSet(opcode, 20);
6215       imm32 = ThumbExpandImm_C(
6216           opcode, APSR_C,
6217           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6218       if (BadReg(Rd) || BadReg(Rn))
6219         return false;
6220       break;
6221     case eEncodingA1:
6222       Rd = Bits32(opcode, 15, 12);
6223       Rn = Bits32(opcode, 19, 16);
6224       setflags = BitIsSet(opcode, 20);
6225       imm32 =
6226           ARMExpandImm_C(opcode, APSR_C,
6227                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6228 
6229       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6230       // instructions;
6231       if (Rd == 15 && setflags)
6232         return EmulateSUBSPcLrEtc(opcode, encoding);
6233       break;
6234     default:
6235       return false;
6236     }
6237 
6238     // Read the first operand.
6239     uint32_t val1 = ReadCoreReg(Rn, &success);
6240     if (!success)
6241       return false;
6242 
6243     uint32_t result = val1 & ~imm32;
6244 
6245     EmulateInstruction::Context context;
6246     context.type = EmulateInstruction::eContextImmediate;
6247     context.SetNoArgs();
6248 
6249     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6250       return false;
6251   }
6252   return true;
6253 }
6254 
6255 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6256 // the complement of an optionally-shifted register value, and writes the
6257 // result to the destination register. It can optionally update the condition
6258 // flags based on the result.
EmulateBICReg(const uint32_t opcode,const ARMEncoding encoding)6259 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6260                                           const ARMEncoding encoding) {
6261 #if 0
6262     // ARM pseudo code...
6263     if ConditionPassed() then
6264         EncodingSpecificOperations();
6265         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6266         result = R[n] AND NOT(shifted);
6267         if d == 15 then         // Can only occur for ARM encoding
6268             ALUWritePC(result); // setflags is always FALSE here
6269         else
6270             R[d] = result;
6271             if setflags then
6272                 APSR.N = result<31>;
6273                 APSR.Z = IsZeroBit(result);
6274                 APSR.C = carry;
6275                 // APSR.V unchanged
6276 #endif
6277 
6278   bool success = false;
6279 
6280   if (ConditionPassed(opcode)) {
6281     uint32_t Rd, Rn, Rm;
6282     ARM_ShifterType shift_t;
6283     uint32_t shift_n; // the shift applied to the value read from Rm
6284     bool setflags;
6285     uint32_t carry;
6286     switch (encoding) {
6287     case eEncodingT1:
6288       Rd = Rn = Bits32(opcode, 2, 0);
6289       Rm = Bits32(opcode, 5, 3);
6290       setflags = !InITBlock();
6291       shift_t = SRType_LSL;
6292       shift_n = 0;
6293       break;
6294     case eEncodingT2:
6295       Rd = Bits32(opcode, 11, 8);
6296       Rn = Bits32(opcode, 19, 16);
6297       Rm = Bits32(opcode, 3, 0);
6298       setflags = BitIsSet(opcode, 20);
6299       shift_n = DecodeImmShiftThumb(opcode, shift_t);
6300       if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6301         return false;
6302       break;
6303     case eEncodingA1:
6304       Rd = Bits32(opcode, 15, 12);
6305       Rn = Bits32(opcode, 19, 16);
6306       Rm = Bits32(opcode, 3, 0);
6307       setflags = BitIsSet(opcode, 20);
6308       shift_n = DecodeImmShiftARM(opcode, shift_t);
6309 
6310       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6311       // instructions;
6312       if (Rd == 15 && setflags)
6313         return EmulateSUBSPcLrEtc(opcode, encoding);
6314       break;
6315     default:
6316       return false;
6317     }
6318 
6319     // Read the first operand.
6320     uint32_t val1 = ReadCoreReg(Rn, &success);
6321     if (!success)
6322       return false;
6323 
6324     // Read the second operand.
6325     uint32_t val2 = ReadCoreReg(Rm, &success);
6326     if (!success)
6327       return false;
6328 
6329     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6330     if (!success)
6331       return false;
6332     uint32_t result = val1 & ~shifted;
6333 
6334     EmulateInstruction::Context context;
6335     context.type = EmulateInstruction::eContextImmediate;
6336     context.SetNoArgs();
6337 
6338     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6339       return false;
6340   }
6341   return true;
6342 }
6343 
6344 // LDR (immediate, ARM) calculates an address from a base register value and an
6345 // immediate offset, loads a word
6346 // from memory, and writes it to a register.  It can use offset, post-indexed,
6347 // or pre-indexed addressing.
EmulateLDRImmediateARM(const uint32_t opcode,const ARMEncoding encoding)6348 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6349                                                    const ARMEncoding encoding) {
6350 #if 0
6351     if ConditionPassed() then
6352         EncodingSpecificOperations();
6353         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6354         address = if index then offset_addr else R[n];
6355         data = MemU[address,4];
6356         if wback then R[n] = offset_addr;
6357         if t == 15 then
6358             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6359         elsif UnalignedSupport() || address<1:0> = '00' then
6360             R[t] = data;
6361         else // Can only apply before ARMv7
6362             R[t] = ROR(data, 8*UInt(address<1:0>));
6363 #endif
6364 
6365   bool success = false;
6366 
6367   if (ConditionPassed(opcode)) {
6368     const uint32_t addr_byte_size = GetAddressByteSize();
6369 
6370     uint32_t t;
6371     uint32_t n;
6372     uint32_t imm32;
6373     bool index;
6374     bool add;
6375     bool wback;
6376 
6377     switch (encoding) {
6378     case eEncodingA1:
6379       // if Rn == '1111' then SEE LDR (literal);
6380       // if P == '0' && W == '1' then SEE LDRT;
6381       // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6382       // '000000000100' then SEE POP;
6383       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6384       t = Bits32(opcode, 15, 12);
6385       n = Bits32(opcode, 19, 16);
6386       imm32 = Bits32(opcode, 11, 0);
6387 
6388       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6389       // (W == '1');
6390       index = BitIsSet(opcode, 24);
6391       add = BitIsSet(opcode, 23);
6392       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6393 
6394       // if wback && n == t then UNPREDICTABLE;
6395       if (wback && (n == t))
6396         return false;
6397 
6398       break;
6399 
6400     default:
6401       return false;
6402     }
6403 
6404     addr_t address;
6405     addr_t offset_addr;
6406     addr_t base_address = ReadCoreReg(n, &success);
6407     if (!success)
6408       return false;
6409 
6410     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6411     if (add)
6412       offset_addr = base_address + imm32;
6413     else
6414       offset_addr = base_address - imm32;
6415 
6416     // address = if index then offset_addr else R[n];
6417     if (index)
6418       address = offset_addr;
6419     else
6420       address = base_address;
6421 
6422     // data = MemU[address,4];
6423 
6424     RegisterInfo base_reg;
6425     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6426 
6427     EmulateInstruction::Context context;
6428     context.type = eContextRegisterLoad;
6429     context.SetRegisterPlusOffset(base_reg, address - base_address);
6430 
6431     uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6432     if (!success)
6433       return false;
6434 
6435     // if wback then R[n] = offset_addr;
6436     if (wback) {
6437       context.type = eContextAdjustBaseRegister;
6438       context.SetAddress(offset_addr);
6439       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6440                                  offset_addr))
6441         return false;
6442     }
6443 
6444     // if t == 15 then
6445     if (t == 15) {
6446       // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6447       if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6448         // LoadWritePC (data);
6449         context.type = eContextRegisterLoad;
6450         context.SetRegisterPlusOffset(base_reg, address - base_address);
6451         LoadWritePC(context, data);
6452       } else
6453         return false;
6454     }
6455     // elsif UnalignedSupport() || address<1:0> = '00' then
6456     else if (UnalignedSupport() ||
6457              (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6458       // R[t] = data;
6459       context.type = eContextRegisterLoad;
6460       context.SetRegisterPlusOffset(base_reg, address - base_address);
6461       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6462                                  data))
6463         return false;
6464     }
6465     // else // Can only apply before ARMv7
6466     else {
6467       // R[t] = ROR(data, 8*UInt(address<1:0>));
6468       data = ROR(data, Bits32(address, 1, 0), &success);
6469       if (!success)
6470         return false;
6471       context.type = eContextRegisterLoad;
6472       context.SetImmediate(data);
6473       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6474                                  data))
6475         return false;
6476     }
6477   }
6478   return true;
6479 }
6480 
6481 // LDR (register) calculates an address from a base register value and an offset
6482 // register value, loads a word
6483 // from memory, and writes it to a register.  The offset register value can
6484 // optionally be shifted.
EmulateLDRRegister(const uint32_t opcode,const ARMEncoding encoding)6485 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6486                                                const ARMEncoding encoding) {
6487 #if 0
6488     if ConditionPassed() then
6489         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6490         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6491         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6492         address = if index then offset_addr else R[n];
6493         data = MemU[address,4];
6494         if wback then R[n] = offset_addr;
6495         if t == 15 then
6496             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6497         elsif UnalignedSupport() || address<1:0> = '00' then
6498             R[t] = data;
6499         else // Can only apply before ARMv7
6500             if CurrentInstrSet() == InstrSet_ARM then
6501                 R[t] = ROR(data, 8*UInt(address<1:0>));
6502             else
6503                 R[t] = bits(32) UNKNOWN;
6504 #endif
6505 
6506   bool success = false;
6507 
6508   if (ConditionPassed(opcode)) {
6509     const uint32_t addr_byte_size = GetAddressByteSize();
6510 
6511     uint32_t t;
6512     uint32_t n;
6513     uint32_t m;
6514     bool index;
6515     bool add;
6516     bool wback;
6517     ARM_ShifterType shift_t;
6518     uint32_t shift_n;
6519 
6520     switch (encoding) {
6521     case eEncodingT1:
6522       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6523       // in ThumbEE";
6524       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6525       t = Bits32(opcode, 2, 0);
6526       n = Bits32(opcode, 5, 3);
6527       m = Bits32(opcode, 8, 6);
6528 
6529       // index = TRUE; add = TRUE; wback = FALSE;
6530       index = true;
6531       add = true;
6532       wback = false;
6533 
6534       // (shift_t, shift_n) = (SRType_LSL, 0);
6535       shift_t = SRType_LSL;
6536       shift_n = 0;
6537 
6538       break;
6539 
6540     case eEncodingT2:
6541       // if Rn == '1111' then SEE LDR (literal);
6542       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6543       t = Bits32(opcode, 15, 12);
6544       n = Bits32(opcode, 19, 16);
6545       m = Bits32(opcode, 3, 0);
6546 
6547       // index = TRUE; add = TRUE; wback = FALSE;
6548       index = true;
6549       add = true;
6550       wback = false;
6551 
6552       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6553       shift_t = SRType_LSL;
6554       shift_n = Bits32(opcode, 5, 4);
6555 
6556       // if BadReg(m) then UNPREDICTABLE;
6557       if (BadReg(m))
6558         return false;
6559 
6560       // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6561       if ((t == 15) && InITBlock() && !LastInITBlock())
6562         return false;
6563 
6564       break;
6565 
6566     case eEncodingA1: {
6567       // if P == '0' && W == '1' then SEE LDRT;
6568       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6569       t = Bits32(opcode, 15, 12);
6570       n = Bits32(opcode, 19, 16);
6571       m = Bits32(opcode, 3, 0);
6572 
6573       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6574       // (W == '1');
6575       index = BitIsSet(opcode, 24);
6576       add = BitIsSet(opcode, 23);
6577       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6578 
6579       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6580       uint32_t type = Bits32(opcode, 6, 5);
6581       uint32_t imm5 = Bits32(opcode, 11, 7);
6582       shift_n = DecodeImmShift(type, imm5, shift_t);
6583 
6584       // if m == 15 then UNPREDICTABLE;
6585       if (m == 15)
6586         return false;
6587 
6588       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6589       if (wback && ((n == 15) || (n == t)))
6590         return false;
6591     } break;
6592 
6593     default:
6594       return false;
6595     }
6596 
6597     uint32_t Rm =
6598         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6599     if (!success)
6600       return false;
6601 
6602     uint32_t Rn =
6603         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6604     if (!success)
6605       return false;
6606 
6607     addr_t offset_addr;
6608     addr_t address;
6609 
6610     // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is
6611     // an application level alias for the CPSR".
6612     addr_t offset =
6613         Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6614     if (!success)
6615       return false;
6616 
6617     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6618     if (add)
6619       offset_addr = Rn + offset;
6620     else
6621       offset_addr = Rn - offset;
6622 
6623     // address = if index then offset_addr else R[n];
6624     if (index)
6625       address = offset_addr;
6626     else
6627       address = Rn;
6628 
6629     // data = MemU[address,4];
6630     RegisterInfo base_reg;
6631     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6632 
6633     EmulateInstruction::Context context;
6634     context.type = eContextRegisterLoad;
6635     context.SetRegisterPlusOffset(base_reg, address - Rn);
6636 
6637     uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6638     if (!success)
6639       return false;
6640 
6641     // if wback then R[n] = offset_addr;
6642     if (wback) {
6643       context.type = eContextAdjustBaseRegister;
6644       context.SetAddress(offset_addr);
6645       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6646                                  offset_addr))
6647         return false;
6648     }
6649 
6650     // if t == 15 then
6651     if (t == 15) {
6652       // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6653       if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6654         context.type = eContextRegisterLoad;
6655         context.SetRegisterPlusOffset(base_reg, address - Rn);
6656         LoadWritePC(context, data);
6657       } else
6658         return false;
6659     }
6660     // elsif UnalignedSupport() || address<1:0> = '00' then
6661     else if (UnalignedSupport() ||
6662              (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6663       // R[t] = data;
6664       context.type = eContextRegisterLoad;
6665       context.SetRegisterPlusOffset(base_reg, address - Rn);
6666       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6667                                  data))
6668         return false;
6669     } else // Can only apply before ARMv7
6670     {
6671       // if CurrentInstrSet() == InstrSet_ARM then
6672       if (CurrentInstrSet() == eModeARM) {
6673         // R[t] = ROR(data, 8*UInt(address<1:0>));
6674         data = ROR(data, Bits32(address, 1, 0), &success);
6675         if (!success)
6676           return false;
6677         context.type = eContextRegisterLoad;
6678         context.SetImmediate(data);
6679         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6680                                    data))
6681           return false;
6682       } else {
6683         // R[t] = bits(32) UNKNOWN;
6684         WriteBits32Unknown(t);
6685       }
6686     }
6687   }
6688   return true;
6689 }
6690 
6691 // LDRB (immediate, Thumb)
EmulateLDRBImmediate(const uint32_t opcode,const ARMEncoding encoding)6692 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6693                                                  const ARMEncoding encoding) {
6694 #if 0
6695     if ConditionPassed() then
6696         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6697         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6698         address = if index then offset_addr else R[n];
6699         R[t] = ZeroExtend(MemU[address,1], 32);
6700         if wback then R[n] = offset_addr;
6701 #endif
6702 
6703   bool success = false;
6704 
6705   if (ConditionPassed(opcode)) {
6706     uint32_t t;
6707     uint32_t n;
6708     uint32_t imm32;
6709     bool index;
6710     bool add;
6711     bool wback;
6712 
6713     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6714     switch (encoding) {
6715     case eEncodingT1:
6716       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6717       t = Bits32(opcode, 2, 0);
6718       n = Bits32(opcode, 5, 3);
6719       imm32 = Bits32(opcode, 10, 6);
6720 
6721       // index = TRUE; add = TRUE; wback = FALSE;
6722       index = true;
6723       add = true;
6724       wback = false;
6725 
6726       break;
6727 
6728     case eEncodingT2:
6729       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6730       t = Bits32(opcode, 15, 12);
6731       n = Bits32(opcode, 19, 16);
6732       imm32 = Bits32(opcode, 11, 0);
6733 
6734       // index = TRUE; add = TRUE; wback = FALSE;
6735       index = true;
6736       add = true;
6737       wback = false;
6738 
6739       // if Rt == '1111' then SEE PLD;
6740       if (t == 15)
6741         return false; // PLD is not implemented yet
6742 
6743       // if Rn == '1111' then SEE LDRB (literal);
6744       if (n == 15)
6745         return EmulateLDRBLiteral(opcode, eEncodingT1);
6746 
6747       // if t == 13 then UNPREDICTABLE;
6748       if (t == 13)
6749         return false;
6750 
6751       break;
6752 
6753     case eEncodingT3:
6754       // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6755       // if P == '0' && W == '0' then UNDEFINED;
6756       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6757         return false;
6758 
6759       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6760       t = Bits32(opcode, 15, 12);
6761       n = Bits32(opcode, 19, 16);
6762       imm32 = Bits32(opcode, 7, 0);
6763 
6764       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6765       index = BitIsSet(opcode, 10);
6766       add = BitIsSet(opcode, 9);
6767       wback = BitIsSet(opcode, 8);
6768 
6769       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6770       if (t == 15)
6771         return false; // PLD is not implemented yet
6772 
6773       // if Rn == '1111' then SEE LDRB (literal);
6774       if (n == 15)
6775         return EmulateLDRBLiteral(opcode, eEncodingT1);
6776 
6777       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6778       if (BadReg(t) || (wback && (n == t)))
6779         return false;
6780 
6781       break;
6782 
6783     default:
6784       return false;
6785     }
6786 
6787     uint32_t Rn =
6788         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6789     if (!success)
6790       return false;
6791 
6792     addr_t address;
6793     addr_t offset_addr;
6794 
6795     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6796     if (add)
6797       offset_addr = Rn + imm32;
6798     else
6799       offset_addr = Rn - imm32;
6800 
6801     // address = if index then offset_addr else R[n];
6802     if (index)
6803       address = offset_addr;
6804     else
6805       address = Rn;
6806 
6807     // R[t] = ZeroExtend(MemU[address,1], 32);
6808     RegisterInfo base_reg;
6809     RegisterInfo data_reg;
6810     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6811     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6812 
6813     EmulateInstruction::Context context;
6814     context.type = eContextRegisterLoad;
6815     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6816 
6817     uint64_t data = MemURead(context, address, 1, 0, &success);
6818     if (!success)
6819       return false;
6820 
6821     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6822       return false;
6823 
6824     // if wback then R[n] = offset_addr;
6825     if (wback) {
6826       context.type = eContextAdjustBaseRegister;
6827       context.SetAddress(offset_addr);
6828       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6829                                  offset_addr))
6830         return false;
6831     }
6832   }
6833   return true;
6834 }
6835 
6836 // LDRB (literal) calculates an address from the PC value and an immediate
6837 // offset, loads a byte from memory,
6838 // zero-extends it to form a 32-bit word and writes it to a register.
EmulateLDRBLiteral(const uint32_t opcode,const ARMEncoding encoding)6839 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6840                                                const ARMEncoding encoding) {
6841 #if 0
6842     if ConditionPassed() then
6843         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6844         base = Align(PC,4);
6845         address = if add then (base + imm32) else (base - imm32);
6846         R[t] = ZeroExtend(MemU[address,1], 32);
6847 #endif
6848 
6849   bool success = false;
6850 
6851   if (ConditionPassed(opcode)) {
6852     uint32_t t;
6853     uint32_t imm32;
6854     bool add;
6855     switch (encoding) {
6856     case eEncodingT1:
6857       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6858       t = Bits32(opcode, 15, 12);
6859       imm32 = Bits32(opcode, 11, 0);
6860       add = BitIsSet(opcode, 23);
6861 
6862       // if Rt == '1111' then SEE PLD;
6863       if (t == 15)
6864         return false; // PLD is not implemented yet
6865 
6866       // if t == 13 then UNPREDICTABLE;
6867       if (t == 13)
6868         return false;
6869 
6870       break;
6871 
6872     case eEncodingA1:
6873       // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6874       t = Bits32(opcode, 15, 12);
6875       imm32 = Bits32(opcode, 11, 0);
6876       add = BitIsSet(opcode, 23);
6877 
6878       // if t == 15 then UNPREDICTABLE;
6879       if (t == 15)
6880         return false;
6881       break;
6882 
6883     default:
6884       return false;
6885     }
6886 
6887     // base = Align(PC,4);
6888     uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6889     if (!success)
6890       return false;
6891 
6892     uint32_t base = AlignPC(pc_val);
6893 
6894     addr_t address;
6895     // address = if add then (base + imm32) else (base - imm32);
6896     if (add)
6897       address = base + imm32;
6898     else
6899       address = base - imm32;
6900 
6901     // R[t] = ZeroExtend(MemU[address,1], 32);
6902     EmulateInstruction::Context context;
6903     context.type = eContextRelativeBranchImmediate;
6904     context.SetImmediate(address - base);
6905 
6906     uint64_t data = MemURead(context, address, 1, 0, &success);
6907     if (!success)
6908       return false;
6909 
6910     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6911       return false;
6912   }
6913   return true;
6914 }
6915 
6916 // LDRB (register) calculates an address from a base register value and an
6917 // offset rigister value, loads a byte from memory, zero-extends it to form a
6918 // 32-bit word, and writes it to a register. The offset register value can
6919 // optionally be shifted.
EmulateLDRBRegister(const uint32_t opcode,const ARMEncoding encoding)6920 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6921                                                 const ARMEncoding encoding) {
6922 #if 0
6923     if ConditionPassed() then
6924         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6925         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6926         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6927         address = if index then offset_addr else R[n];
6928         R[t] = ZeroExtend(MemU[address,1],32);
6929         if wback then R[n] = offset_addr;
6930 #endif
6931 
6932   bool success = false;
6933 
6934   if (ConditionPassed(opcode)) {
6935     uint32_t t;
6936     uint32_t n;
6937     uint32_t m;
6938     bool index;
6939     bool add;
6940     bool wback;
6941     ARM_ShifterType shift_t;
6942     uint32_t shift_n;
6943 
6944     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6945     switch (encoding) {
6946     case eEncodingT1:
6947       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6948       t = Bits32(opcode, 2, 0);
6949       n = Bits32(opcode, 5, 3);
6950       m = Bits32(opcode, 8, 6);
6951 
6952       // index = TRUE; add = TRUE; wback = FALSE;
6953       index = true;
6954       add = true;
6955       wback = false;
6956 
6957       // (shift_t, shift_n) = (SRType_LSL, 0);
6958       shift_t = SRType_LSL;
6959       shift_n = 0;
6960       break;
6961 
6962     case eEncodingT2:
6963       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6964       t = Bits32(opcode, 15, 12);
6965       n = Bits32(opcode, 19, 16);
6966       m = Bits32(opcode, 3, 0);
6967 
6968       // index = TRUE; add = TRUE; wback = FALSE;
6969       index = true;
6970       add = true;
6971       wback = false;
6972 
6973       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6974       shift_t = SRType_LSL;
6975       shift_n = Bits32(opcode, 5, 4);
6976 
6977       // if Rt == '1111' then SEE PLD;
6978       if (t == 15)
6979         return false; // PLD is not implemented yet
6980 
6981       // if Rn == '1111' then SEE LDRB (literal);
6982       if (n == 15)
6983         return EmulateLDRBLiteral(opcode, eEncodingT1);
6984 
6985       // if t == 13 || BadReg(m) then UNPREDICTABLE;
6986       if ((t == 13) || BadReg(m))
6987         return false;
6988       break;
6989 
6990     case eEncodingA1: {
6991       // if P == '0' && W == '1' then SEE LDRBT;
6992       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6993       t = Bits32(opcode, 15, 12);
6994       n = Bits32(opcode, 19, 16);
6995       m = Bits32(opcode, 3, 0);
6996 
6997       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6998       // (W == '1');
6999       index = BitIsSet(opcode, 24);
7000       add = BitIsSet(opcode, 23);
7001       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7002 
7003       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7004       uint32_t type = Bits32(opcode, 6, 5);
7005       uint32_t imm5 = Bits32(opcode, 11, 7);
7006       shift_n = DecodeImmShift(type, imm5, shift_t);
7007 
7008       // if t == 15 || m == 15 then UNPREDICTABLE;
7009       if ((t == 15) || (m == 15))
7010         return false;
7011 
7012       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7013       if (wback && ((n == 15) || (n == t)))
7014         return false;
7015     } break;
7016 
7017     default:
7018       return false;
7019     }
7020 
7021     addr_t offset_addr;
7022     addr_t address;
7023 
7024     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7025     uint32_t Rm =
7026         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7027     if (!success)
7028       return false;
7029 
7030     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7031     if (!success)
7032       return false;
7033 
7034     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7035     uint32_t Rn =
7036         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7037     if (!success)
7038       return false;
7039 
7040     if (add)
7041       offset_addr = Rn + offset;
7042     else
7043       offset_addr = Rn - offset;
7044 
7045     // address = if index then offset_addr else R[n];
7046     if (index)
7047       address = offset_addr;
7048     else
7049       address = Rn;
7050 
7051     // R[t] = ZeroExtend(MemU[address,1],32);
7052     RegisterInfo base_reg;
7053     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7054 
7055     EmulateInstruction::Context context;
7056     context.type = eContextRegisterLoad;
7057     context.SetRegisterPlusOffset(base_reg, address - Rn);
7058 
7059     uint64_t data = MemURead(context, address, 1, 0, &success);
7060     if (!success)
7061       return false;
7062 
7063     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7064       return false;
7065 
7066     // if wback then R[n] = offset_addr;
7067     if (wback) {
7068       context.type = eContextAdjustBaseRegister;
7069       context.SetAddress(offset_addr);
7070       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7071                                  offset_addr))
7072         return false;
7073     }
7074   }
7075   return true;
7076 }
7077 
7078 // LDRH (immediate, Thumb) calculates an address from a base register value and
7079 // an immediate offset, loads a
7080 // halfword from memory, zero-extends it to form a 32-bit word, and writes it
7081 // to a register.  It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRHImmediate(const uint32_t opcode,const ARMEncoding encoding)7082 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7083                                                  const ARMEncoding encoding) {
7084 #if 0
7085     if ConditionPassed() then
7086         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7087         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7088         address = if index then offset_addr else R[n];
7089         data = MemU[address,2];
7090         if wback then R[n] = offset_addr;
7091         if UnalignedSupport() || address<0> = '0' then
7092             R[t] = ZeroExtend(data, 32);
7093         else // Can only apply before ARMv7
7094             R[t] = bits(32) UNKNOWN;
7095 #endif
7096 
7097   bool success = false;
7098 
7099   if (ConditionPassed(opcode)) {
7100     uint32_t t;
7101     uint32_t n;
7102     uint32_t imm32;
7103     bool index;
7104     bool add;
7105     bool wback;
7106 
7107     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7108     switch (encoding) {
7109     case eEncodingT1:
7110       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7111       t = Bits32(opcode, 2, 0);
7112       n = Bits32(opcode, 5, 3);
7113       imm32 = Bits32(opcode, 10, 6) << 1;
7114 
7115       // index = TRUE; add = TRUE; wback = FALSE;
7116       index = true;
7117       add = true;
7118       wback = false;
7119 
7120       break;
7121 
7122     case eEncodingT2:
7123       // if Rt == '1111' then SEE "Unallocated memory hints";
7124       // if Rn == '1111' then SEE LDRH (literal);
7125       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7126       t = Bits32(opcode, 15, 12);
7127       n = Bits32(opcode, 19, 16);
7128       imm32 = Bits32(opcode, 11, 0);
7129 
7130       // index = TRUE; add = TRUE; wback = FALSE;
7131       index = true;
7132       add = true;
7133       wback = false;
7134 
7135       // if t == 13 then UNPREDICTABLE;
7136       if (t == 13)
7137         return false;
7138       break;
7139 
7140     case eEncodingT3:
7141       // if Rn == '1111' then SEE LDRH (literal);
7142       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7143       // "Unallocated memory hints";
7144       // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7145       // if P == '0' && W == '0' then UNDEFINED;
7146       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7147         return false;
7148 
7149       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7150       t = Bits32(opcode, 15, 12);
7151       n = Bits32(opcode, 19, 16);
7152       imm32 = Bits32(opcode, 7, 0);
7153 
7154       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7155       index = BitIsSet(opcode, 10);
7156       add = BitIsSet(opcode, 9);
7157       wback = BitIsSet(opcode, 8);
7158 
7159       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7160       if (BadReg(t) || (wback && (n == t)))
7161         return false;
7162       break;
7163 
7164     default:
7165       return false;
7166     }
7167 
7168     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7169     uint32_t Rn =
7170         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7171     if (!success)
7172       return false;
7173 
7174     addr_t offset_addr;
7175     addr_t address;
7176 
7177     if (add)
7178       offset_addr = Rn + imm32;
7179     else
7180       offset_addr = Rn - imm32;
7181 
7182     // address = if index then offset_addr else R[n];
7183     if (index)
7184       address = offset_addr;
7185     else
7186       address = Rn;
7187 
7188     // data = MemU[address,2];
7189     RegisterInfo base_reg;
7190     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7191 
7192     EmulateInstruction::Context context;
7193     context.type = eContextRegisterLoad;
7194     context.SetRegisterPlusOffset(base_reg, address - Rn);
7195 
7196     uint64_t data = MemURead(context, address, 2, 0, &success);
7197     if (!success)
7198       return false;
7199 
7200     // if wback then R[n] = offset_addr;
7201     if (wback) {
7202       context.type = eContextAdjustBaseRegister;
7203       context.SetAddress(offset_addr);
7204       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7205                                  offset_addr))
7206         return false;
7207     }
7208 
7209     // if UnalignedSupport() || address<0> = '0' then
7210     if (UnalignedSupport() || BitIsClear(address, 0)) {
7211       // R[t] = ZeroExtend(data, 32);
7212       context.type = eContextRegisterLoad;
7213       context.SetRegisterPlusOffset(base_reg, address - Rn);
7214       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7215                                  data))
7216         return false;
7217     } else // Can only apply before ARMv7
7218     {
7219       // R[t] = bits(32) UNKNOWN;
7220       WriteBits32Unknown(t);
7221     }
7222   }
7223   return true;
7224 }
7225 
7226 // LDRH (literal) calculates an address from the PC value and an immediate
7227 // offset, loads a halfword from memory,
7228 // zero-extends it to form a 32-bit word, and writes it to a register.
EmulateLDRHLiteral(const uint32_t opcode,const ARMEncoding encoding)7229 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7230                                                const ARMEncoding encoding) {
7231 #if 0
7232     if ConditionPassed() then
7233         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7234         base = Align(PC,4);
7235         address = if add then (base + imm32) else (base - imm32);
7236         data = MemU[address,2];
7237         if UnalignedSupport() || address<0> = '0' then
7238             R[t] = ZeroExtend(data, 32);
7239         else // Can only apply before ARMv7
7240             R[t] = bits(32) UNKNOWN;
7241 #endif
7242 
7243   bool success = false;
7244 
7245   if (ConditionPassed(opcode)) {
7246     uint32_t t;
7247     uint32_t imm32;
7248     bool add;
7249 
7250     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7251     switch (encoding) {
7252     case eEncodingT1:
7253       // if Rt == '1111' then SEE "Unallocated memory hints";
7254       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7255       t = Bits32(opcode, 15, 12);
7256       imm32 = Bits32(opcode, 11, 0);
7257       add = BitIsSet(opcode, 23);
7258 
7259       // if t == 13 then UNPREDICTABLE;
7260       if (t == 13)
7261         return false;
7262 
7263       break;
7264 
7265     case eEncodingA1: {
7266       uint32_t imm4H = Bits32(opcode, 11, 8);
7267       uint32_t imm4L = Bits32(opcode, 3, 0);
7268 
7269       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7270       t = Bits32(opcode, 15, 12);
7271       imm32 = (imm4H << 4) | imm4L;
7272       add = BitIsSet(opcode, 23);
7273 
7274       // if t == 15 then UNPREDICTABLE;
7275       if (t == 15)
7276         return false;
7277       break;
7278     }
7279 
7280     default:
7281       return false;
7282     }
7283 
7284     // base = Align(PC,4);
7285     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7286     if (!success)
7287       return false;
7288 
7289     addr_t base = AlignPC(pc_value);
7290     addr_t address;
7291 
7292     // address = if add then (base + imm32) else (base - imm32);
7293     if (add)
7294       address = base + imm32;
7295     else
7296       address = base - imm32;
7297 
7298     // data = MemU[address,2];
7299     RegisterInfo base_reg;
7300     GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7301 
7302     EmulateInstruction::Context context;
7303     context.type = eContextRegisterLoad;
7304     context.SetRegisterPlusOffset(base_reg, address - base);
7305 
7306     uint64_t data = MemURead(context, address, 2, 0, &success);
7307     if (!success)
7308       return false;
7309 
7310     // if UnalignedSupport() || address<0> = '0' then
7311     if (UnalignedSupport() || BitIsClear(address, 0)) {
7312       // R[t] = ZeroExtend(data, 32);
7313       context.type = eContextRegisterLoad;
7314       context.SetRegisterPlusOffset(base_reg, address - base);
7315       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7316                                  data))
7317         return false;
7318 
7319     } else // Can only apply before ARMv7
7320     {
7321       // R[t] = bits(32) UNKNOWN;
7322       WriteBits32Unknown(t);
7323     }
7324   }
7325   return true;
7326 }
7327 
7328 // LDRH (literal) calculates an address from a base register value and an offset
7329 // register value, loads a halfword
7330 // from memory, zero-extends it to form a 32-bit word, and writes it to a
7331 // register.  The offset register value can be shifted left by 0, 1, 2, or 3
7332 // bits.
EmulateLDRHRegister(const uint32_t opcode,const ARMEncoding encoding)7333 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7334                                                 const ARMEncoding encoding) {
7335 #if 0
7336     if ConditionPassed() then
7337         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7338         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7339         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7340         address = if index then offset_addr else R[n];
7341         data = MemU[address,2];
7342         if wback then R[n] = offset_addr;
7343         if UnalignedSupport() || address<0> = '0' then
7344             R[t] = ZeroExtend(data, 32);
7345         else // Can only apply before ARMv7
7346             R[t] = bits(32) UNKNOWN;
7347 #endif
7348 
7349   bool success = false;
7350 
7351   if (ConditionPassed(opcode)) {
7352     uint32_t t;
7353     uint32_t n;
7354     uint32_t m;
7355     bool index;
7356     bool add;
7357     bool wback;
7358     ARM_ShifterType shift_t;
7359     uint32_t shift_n;
7360 
7361     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7362     switch (encoding) {
7363     case eEncodingT1:
7364       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7365       // in ThumbEE";
7366       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7367       t = Bits32(opcode, 2, 0);
7368       n = Bits32(opcode, 5, 3);
7369       m = Bits32(opcode, 8, 6);
7370 
7371       // index = TRUE; add = TRUE; wback = FALSE;
7372       index = true;
7373       add = true;
7374       wback = false;
7375 
7376       // (shift_t, shift_n) = (SRType_LSL, 0);
7377       shift_t = SRType_LSL;
7378       shift_n = 0;
7379 
7380       break;
7381 
7382     case eEncodingT2:
7383       // if Rn == '1111' then SEE LDRH (literal);
7384       // if Rt == '1111' then SEE "Unallocated memory hints";
7385       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7386       t = Bits32(opcode, 15, 12);
7387       n = Bits32(opcode, 19, 16);
7388       m = Bits32(opcode, 3, 0);
7389 
7390       // index = TRUE; add = TRUE; wback = FALSE;
7391       index = true;
7392       add = true;
7393       wback = false;
7394 
7395       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7396       shift_t = SRType_LSL;
7397       shift_n = Bits32(opcode, 5, 4);
7398 
7399       // if t == 13 || BadReg(m) then UNPREDICTABLE;
7400       if ((t == 13) || BadReg(m))
7401         return false;
7402       break;
7403 
7404     case eEncodingA1:
7405       // if P == '0' && W == '1' then SEE LDRHT;
7406       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7407       t = Bits32(opcode, 15, 12);
7408       n = Bits32(opcode, 19, 16);
7409       m = Bits32(opcode, 3, 0);
7410 
7411       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7412       // (W == '1');
7413       index = BitIsSet(opcode, 24);
7414       add = BitIsSet(opcode, 23);
7415       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7416 
7417       // (shift_t, shift_n) = (SRType_LSL, 0);
7418       shift_t = SRType_LSL;
7419       shift_n = 0;
7420 
7421       // if t == 15 || m == 15 then UNPREDICTABLE;
7422       if ((t == 15) || (m == 15))
7423         return false;
7424 
7425       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7426       if (wback && ((n == 15) || (n == t)))
7427         return false;
7428 
7429       break;
7430 
7431     default:
7432       return false;
7433     }
7434 
7435     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7436 
7437     uint64_t Rm =
7438         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7439     if (!success)
7440       return false;
7441 
7442     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7443     if (!success)
7444       return false;
7445 
7446     addr_t offset_addr;
7447     addr_t address;
7448 
7449     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7450     uint64_t Rn =
7451         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7452     if (!success)
7453       return false;
7454 
7455     if (add)
7456       offset_addr = Rn + offset;
7457     else
7458       offset_addr = Rn - offset;
7459 
7460     // address = if index then offset_addr else R[n];
7461     if (index)
7462       address = offset_addr;
7463     else
7464       address = Rn;
7465 
7466     // data = MemU[address,2];
7467     RegisterInfo base_reg;
7468     RegisterInfo offset_reg;
7469     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7470     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7471 
7472     EmulateInstruction::Context context;
7473     context.type = eContextRegisterLoad;
7474     context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7475     uint64_t data = MemURead(context, address, 2, 0, &success);
7476     if (!success)
7477       return false;
7478 
7479     // if wback then R[n] = offset_addr;
7480     if (wback) {
7481       context.type = eContextAdjustBaseRegister;
7482       context.SetAddress(offset_addr);
7483       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7484                                  offset_addr))
7485         return false;
7486     }
7487 
7488     // if UnalignedSupport() || address<0> = '0' then
7489     if (UnalignedSupport() || BitIsClear(address, 0)) {
7490       // R[t] = ZeroExtend(data, 32);
7491       context.type = eContextRegisterLoad;
7492       context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7493       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7494                                  data))
7495         return false;
7496     } else // Can only apply before ARMv7
7497     {
7498       // R[t] = bits(32) UNKNOWN;
7499       WriteBits32Unknown(t);
7500     }
7501   }
7502   return true;
7503 }
7504 
7505 // LDRSB (immediate) calculates an address from a base register value and an
7506 // immediate offset, loads a byte from
7507 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7508 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSBImmediate(const uint32_t opcode,const ARMEncoding encoding)7509 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7510                                                   const ARMEncoding encoding) {
7511 #if 0
7512     if ConditionPassed() then
7513         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7514         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7515         address = if index then offset_addr else R[n];
7516         R[t] = SignExtend(MemU[address,1], 32);
7517         if wback then R[n] = offset_addr;
7518 #endif
7519 
7520   bool success = false;
7521 
7522   if (ConditionPassed(opcode)) {
7523     uint32_t t;
7524     uint32_t n;
7525     uint32_t imm32;
7526     bool index;
7527     bool add;
7528     bool wback;
7529 
7530     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7531     switch (encoding) {
7532     case eEncodingT1:
7533       // if Rt == '1111' then SEE PLI;
7534       // if Rn == '1111' then SEE LDRSB (literal);
7535       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7536       t = Bits32(opcode, 15, 12);
7537       n = Bits32(opcode, 19, 16);
7538       imm32 = Bits32(opcode, 11, 0);
7539 
7540       // index = TRUE; add = TRUE; wback = FALSE;
7541       index = true;
7542       add = true;
7543       wback = false;
7544 
7545       // if t == 13 then UNPREDICTABLE;
7546       if (t == 13)
7547         return false;
7548 
7549       break;
7550 
7551     case eEncodingT2:
7552       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7553       // if Rn == '1111' then SEE LDRSB (literal);
7554       // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7555       // if P == '0' && W == '0' then UNDEFINED;
7556       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7557         return false;
7558 
7559       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7560       t = Bits32(opcode, 15, 12);
7561       n = Bits32(opcode, 19, 16);
7562       imm32 = Bits32(opcode, 7, 0);
7563 
7564       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7565       index = BitIsSet(opcode, 10);
7566       add = BitIsSet(opcode, 9);
7567       wback = BitIsSet(opcode, 8);
7568 
7569       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7570       if (((t == 13) ||
7571            ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7572                           BitIsSet(opcode, 8)))) ||
7573           (wback && (n == t)))
7574         return false;
7575 
7576       break;
7577 
7578     case eEncodingA1: {
7579       // if Rn == '1111' then SEE LDRSB (literal);
7580       // if P == '0' && W == '1' then SEE LDRSBT;
7581       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7582       t = Bits32(opcode, 15, 12);
7583       n = Bits32(opcode, 19, 16);
7584 
7585       uint32_t imm4H = Bits32(opcode, 11, 8);
7586       uint32_t imm4L = Bits32(opcode, 3, 0);
7587       imm32 = (imm4H << 4) | imm4L;
7588 
7589       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7590       // (W == '1');
7591       index = BitIsSet(opcode, 24);
7592       add = BitIsSet(opcode, 23);
7593       wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7594 
7595       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7596       if ((t == 15) || (wback && (n == t)))
7597         return false;
7598 
7599       break;
7600     }
7601 
7602     default:
7603       return false;
7604     }
7605 
7606     uint64_t Rn = ReadCoreReg(n, &success);
7607     if (!success)
7608       return false;
7609 
7610     addr_t offset_addr;
7611     addr_t address;
7612 
7613     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7614     if (add)
7615       offset_addr = Rn + imm32;
7616     else
7617       offset_addr = Rn - imm32;
7618 
7619     // address = if index then offset_addr else R[n];
7620     if (index)
7621       address = offset_addr;
7622     else
7623       address = Rn;
7624 
7625     // R[t] = SignExtend(MemU[address,1], 32);
7626     RegisterInfo base_reg;
7627     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7628 
7629     EmulateInstruction::Context context;
7630     context.type = eContextRegisterLoad;
7631     context.SetRegisterPlusOffset(base_reg, address - Rn);
7632 
7633     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7634     if (!success)
7635       return false;
7636 
7637     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7638     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7639                                (uint64_t)signed_data))
7640       return false;
7641 
7642     // if wback then R[n] = offset_addr;
7643     if (wback) {
7644       context.type = eContextAdjustBaseRegister;
7645       context.SetAddress(offset_addr);
7646       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7647                                  offset_addr))
7648         return false;
7649     }
7650   }
7651 
7652   return true;
7653 }
7654 
7655 // LDRSB (literal) calculates an address from the PC value and an immediate
7656 // offset, loads a byte from memory,
7657 // sign-extends it to form a 32-bit word, and writes tit to a register.
EmulateLDRSBLiteral(const uint32_t opcode,const ARMEncoding encoding)7658 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7659                                                 const ARMEncoding encoding) {
7660 #if 0
7661     if ConditionPassed() then
7662         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7663         base = Align(PC,4);
7664         address = if add then (base + imm32) else (base - imm32);
7665         R[t] = SignExtend(MemU[address,1], 32);
7666 #endif
7667 
7668   bool success = false;
7669 
7670   if (ConditionPassed(opcode)) {
7671     uint32_t t;
7672     uint32_t imm32;
7673     bool add;
7674 
7675     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7676     switch (encoding) {
7677     case eEncodingT1:
7678       // if Rt == '1111' then SEE PLI;
7679       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7680       t = Bits32(opcode, 15, 12);
7681       imm32 = Bits32(opcode, 11, 0);
7682       add = BitIsSet(opcode, 23);
7683 
7684       // if t == 13 then UNPREDICTABLE;
7685       if (t == 13)
7686         return false;
7687 
7688       break;
7689 
7690     case eEncodingA1: {
7691       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7692       t = Bits32(opcode, 15, 12);
7693       uint32_t imm4H = Bits32(opcode, 11, 8);
7694       uint32_t imm4L = Bits32(opcode, 3, 0);
7695       imm32 = (imm4H << 4) | imm4L;
7696       add = BitIsSet(opcode, 23);
7697 
7698       // if t == 15 then UNPREDICTABLE;
7699       if (t == 15)
7700         return false;
7701 
7702       break;
7703     }
7704 
7705     default:
7706       return false;
7707     }
7708 
7709     // base = Align(PC,4);
7710     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7711     if (!success)
7712       return false;
7713     uint64_t base = AlignPC(pc_value);
7714 
7715     // address = if add then (base + imm32) else (base - imm32);
7716     addr_t address;
7717     if (add)
7718       address = base + imm32;
7719     else
7720       address = base - imm32;
7721 
7722     // R[t] = SignExtend(MemU[address,1], 32);
7723     RegisterInfo base_reg;
7724     GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7725 
7726     EmulateInstruction::Context context;
7727     context.type = eContextRegisterLoad;
7728     context.SetRegisterPlusOffset(base_reg, address - base);
7729 
7730     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7731     if (!success)
7732       return false;
7733 
7734     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7735     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7736                                (uint64_t)signed_data))
7737       return false;
7738   }
7739   return true;
7740 }
7741 
7742 // LDRSB (register) calculates an address from a base register value and an
7743 // offset register value, loadsa byte from
7744 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7745 // The offset register value can be shifted left by 0, 1, 2, or 3 bits.
EmulateLDRSBRegister(const uint32_t opcode,const ARMEncoding encoding)7746 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7747                                                  const ARMEncoding encoding) {
7748 #if 0
7749     if ConditionPassed() then
7750         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7751         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7752         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7753         address = if index then offset_addr else R[n];
7754         R[t] = SignExtend(MemU[address,1], 32);
7755         if wback then R[n] = offset_addr;
7756 #endif
7757 
7758   bool success = false;
7759 
7760   if (ConditionPassed(opcode)) {
7761     uint32_t t;
7762     uint32_t n;
7763     uint32_t m;
7764     bool index;
7765     bool add;
7766     bool wback;
7767     ARM_ShifterType shift_t;
7768     uint32_t shift_n;
7769 
7770     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7771     switch (encoding) {
7772     case eEncodingT1:
7773       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7774       t = Bits32(opcode, 2, 0);
7775       n = Bits32(opcode, 5, 3);
7776       m = Bits32(opcode, 8, 6);
7777 
7778       // index = TRUE; add = TRUE; wback = FALSE;
7779       index = true;
7780       add = true;
7781       wback = false;
7782 
7783       // (shift_t, shift_n) = (SRType_LSL, 0);
7784       shift_t = SRType_LSL;
7785       shift_n = 0;
7786 
7787       break;
7788 
7789     case eEncodingT2:
7790       // if Rt == '1111' then SEE PLI;
7791       // if Rn == '1111' then SEE LDRSB (literal);
7792       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7793       t = Bits32(opcode, 15, 12);
7794       n = Bits32(opcode, 19, 16);
7795       m = Bits32(opcode, 3, 0);
7796 
7797       // index = TRUE; add = TRUE; wback = FALSE;
7798       index = true;
7799       add = true;
7800       wback = false;
7801 
7802       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7803       shift_t = SRType_LSL;
7804       shift_n = Bits32(opcode, 5, 4);
7805 
7806       // if t == 13 || BadReg(m) then UNPREDICTABLE;
7807       if ((t == 13) || BadReg(m))
7808         return false;
7809       break;
7810 
7811     case eEncodingA1:
7812       // if P == '0' && W == '1' then SEE LDRSBT;
7813       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7814       t = Bits32(opcode, 15, 12);
7815       n = Bits32(opcode, 19, 16);
7816       m = Bits32(opcode, 3, 0);
7817 
7818       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7819       // (W == '1');
7820       index = BitIsSet(opcode, 24);
7821       add = BitIsSet(opcode, 23);
7822       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7823 
7824       // (shift_t, shift_n) = (SRType_LSL, 0);
7825       shift_t = SRType_LSL;
7826       shift_n = 0;
7827 
7828       // if t == 15 || m == 15 then UNPREDICTABLE;
7829       if ((t == 15) || (m == 15))
7830         return false;
7831 
7832       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7833       if (wback && ((n == 15) || (n == t)))
7834         return false;
7835       break;
7836 
7837     default:
7838       return false;
7839     }
7840 
7841     uint64_t Rm =
7842         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7843     if (!success)
7844       return false;
7845 
7846     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7847     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7848     if (!success)
7849       return false;
7850 
7851     addr_t offset_addr;
7852     addr_t address;
7853 
7854     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7855     uint64_t Rn =
7856         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7857     if (!success)
7858       return false;
7859 
7860     if (add)
7861       offset_addr = Rn + offset;
7862     else
7863       offset_addr = Rn - offset;
7864 
7865     // address = if index then offset_addr else R[n];
7866     if (index)
7867       address = offset_addr;
7868     else
7869       address = Rn;
7870 
7871     // R[t] = SignExtend(MemU[address,1], 32);
7872     RegisterInfo base_reg;
7873     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7874     RegisterInfo offset_reg;
7875     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7876 
7877     EmulateInstruction::Context context;
7878     context.type = eContextRegisterLoad;
7879     context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7880 
7881     uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7882     if (!success)
7883       return false;
7884 
7885     int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7886     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7887                                (uint64_t)signed_data))
7888       return false;
7889 
7890     // if wback then R[n] = offset_addr;
7891     if (wback) {
7892       context.type = eContextAdjustBaseRegister;
7893       context.SetAddress(offset_addr);
7894       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7895                                  offset_addr))
7896         return false;
7897     }
7898   }
7899   return true;
7900 }
7901 
7902 // LDRSH (immediate) calculates an address from a base register value and an
7903 // immediate offset, loads a halfword from
7904 // memory, sign-extends it to form a 32-bit word, and writes it to a register.
7905 // It can use offset, post-indexed, or pre-indexed addressing.
EmulateLDRSHImmediate(const uint32_t opcode,const ARMEncoding encoding)7906 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7907                                                   const ARMEncoding encoding) {
7908 #if 0
7909     if ConditionPassed() then
7910         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7911         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7912         address = if index then offset_addr else R[n];
7913         data = MemU[address,2];
7914         if wback then R[n] = offset_addr;
7915         if UnalignedSupport() || address<0> = '0' then
7916             R[t] = SignExtend(data, 32);
7917         else // Can only apply before ARMv7
7918             R[t] = bits(32) UNKNOWN;
7919 #endif
7920 
7921   bool success = false;
7922 
7923   if (ConditionPassed(opcode)) {
7924     uint32_t t;
7925     uint32_t n;
7926     uint32_t imm32;
7927     bool index;
7928     bool add;
7929     bool wback;
7930 
7931     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7932     switch (encoding) {
7933     case eEncodingT1:
7934       // if Rn == '1111' then SEE LDRSH (literal);
7935       // if Rt == '1111' then SEE "Unallocated memory hints";
7936       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7937       t = Bits32(opcode, 15, 12);
7938       n = Bits32(opcode, 19, 16);
7939       imm32 = Bits32(opcode, 11, 0);
7940 
7941       // index = TRUE; add = TRUE; wback = FALSE;
7942       index = true;
7943       add = true;
7944       wback = false;
7945 
7946       // if t == 13 then UNPREDICTABLE;
7947       if (t == 13)
7948         return false;
7949 
7950       break;
7951 
7952     case eEncodingT2:
7953       // if Rn == '1111' then SEE LDRSH (literal);
7954       // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7955       // "Unallocated memory hints";
7956       // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7957       // if P == '0' && W == '0' then UNDEFINED;
7958       if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7959         return false;
7960 
7961       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7962       t = Bits32(opcode, 15, 12);
7963       n = Bits32(opcode, 19, 16);
7964       imm32 = Bits32(opcode, 7, 0);
7965 
7966       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7967       index = BitIsSet(opcode, 10);
7968       add = BitIsSet(opcode, 9);
7969       wback = BitIsSet(opcode, 8);
7970 
7971       // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7972       if (BadReg(t) || (wback && (n == t)))
7973         return false;
7974 
7975       break;
7976 
7977     case eEncodingA1: {
7978       // if Rn == '1111' then SEE LDRSH (literal);
7979       // if P == '0' && W == '1' then SEE LDRSHT;
7980       // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7981       t = Bits32(opcode, 15, 12);
7982       n = Bits32(opcode, 19, 16);
7983       uint32_t imm4H = Bits32(opcode, 11, 8);
7984       uint32_t imm4L = Bits32(opcode, 3, 0);
7985       imm32 = (imm4H << 4) | imm4L;
7986 
7987       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7988       // (W == '1');
7989       index = BitIsSet(opcode, 24);
7990       add = BitIsSet(opcode, 23);
7991       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7992 
7993       // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7994       if ((t == 15) || (wback && (n == t)))
7995         return false;
7996 
7997       break;
7998     }
7999 
8000     default:
8001       return false;
8002     }
8003 
8004     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8005     uint64_t Rn =
8006         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8007     if (!success)
8008       return false;
8009 
8010     addr_t offset_addr;
8011     if (add)
8012       offset_addr = Rn + imm32;
8013     else
8014       offset_addr = Rn - imm32;
8015 
8016     // address = if index then offset_addr else R[n];
8017     addr_t address;
8018     if (index)
8019       address = offset_addr;
8020     else
8021       address = Rn;
8022 
8023     // data = MemU[address,2];
8024     RegisterInfo base_reg;
8025     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8026 
8027     EmulateInstruction::Context context;
8028     context.type = eContextRegisterLoad;
8029     context.SetRegisterPlusOffset(base_reg, address - Rn);
8030 
8031     uint64_t data = MemURead(context, address, 2, 0, &success);
8032     if (!success)
8033       return false;
8034 
8035     // if wback then R[n] = offset_addr;
8036     if (wback) {
8037       context.type = eContextAdjustBaseRegister;
8038       context.SetAddress(offset_addr);
8039       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8040                                  offset_addr))
8041         return false;
8042     }
8043 
8044     // if UnalignedSupport() || address<0> = '0' then
8045     if (UnalignedSupport() || BitIsClear(address, 0)) {
8046       // R[t] = SignExtend(data, 32);
8047       int64_t signed_data = llvm::SignExtend64<16>(data);
8048       context.type = eContextRegisterLoad;
8049       context.SetRegisterPlusOffset(base_reg, address - Rn);
8050       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8051                                  (uint64_t)signed_data))
8052         return false;
8053     } else // Can only apply before ARMv7
8054     {
8055       // R[t] = bits(32) UNKNOWN;
8056       WriteBits32Unknown(t);
8057     }
8058   }
8059   return true;
8060 }
8061 
8062 // LDRSH (literal) calculates an address from the PC value and an immediate
8063 // offset, loads a halfword from memory,
8064 // sign-extends it to from a 32-bit word, and writes it to a register.
EmulateLDRSHLiteral(const uint32_t opcode,const ARMEncoding encoding)8065 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8066                                                 const ARMEncoding encoding) {
8067 #if 0
8068     if ConditionPassed() then
8069         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8070         base = Align(PC,4);
8071         address = if add then (base + imm32) else (base - imm32);
8072         data = MemU[address,2];
8073         if UnalignedSupport() || address<0> = '0' then
8074             R[t] = SignExtend(data, 32);
8075         else // Can only apply before ARMv7
8076             R[t] = bits(32) UNKNOWN;
8077 #endif
8078 
8079   bool success = false;
8080 
8081   if (ConditionPassed(opcode)) {
8082     uint32_t t;
8083     uint32_t imm32;
8084     bool add;
8085 
8086     // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8087     switch (encoding) {
8088     case eEncodingT1:
8089       // if Rt == '1111' then SEE "Unallocated memory hints";
8090       // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8091       t = Bits32(opcode, 15, 12);
8092       imm32 = Bits32(opcode, 11, 0);
8093       add = BitIsSet(opcode, 23);
8094 
8095       // if t == 13 then UNPREDICTABLE;
8096       if (t == 13)
8097         return false;
8098 
8099       break;
8100 
8101     case eEncodingA1: {
8102       // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8103       t = Bits32(opcode, 15, 12);
8104       uint32_t imm4H = Bits32(opcode, 11, 8);
8105       uint32_t imm4L = Bits32(opcode, 3, 0);
8106       imm32 = (imm4H << 4) | imm4L;
8107       add = BitIsSet(opcode, 23);
8108 
8109       // if t == 15 then UNPREDICTABLE;
8110       if (t == 15)
8111         return false;
8112 
8113       break;
8114     }
8115     default:
8116       return false;
8117     }
8118 
8119     // base = Align(PC,4);
8120     uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8121     if (!success)
8122       return false;
8123 
8124     uint64_t base = AlignPC(pc_value);
8125 
8126     addr_t address;
8127     // address = if add then (base + imm32) else (base - imm32);
8128     if (add)
8129       address = base + imm32;
8130     else
8131       address = base - imm32;
8132 
8133     // data = MemU[address,2];
8134     RegisterInfo base_reg;
8135     GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8136 
8137     EmulateInstruction::Context context;
8138     context.type = eContextRegisterLoad;
8139     context.SetRegisterPlusOffset(base_reg, imm32);
8140 
8141     uint64_t data = MemURead(context, address, 2, 0, &success);
8142     if (!success)
8143       return false;
8144 
8145     // if UnalignedSupport() || address<0> = '0' then
8146     if (UnalignedSupport() || BitIsClear(address, 0)) {
8147       // R[t] = SignExtend(data, 32);
8148       int64_t signed_data = llvm::SignExtend64<16>(data);
8149       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8150                                  (uint64_t)signed_data))
8151         return false;
8152     } else // Can only apply before ARMv7
8153     {
8154       // R[t] = bits(32) UNKNOWN;
8155       WriteBits32Unknown(t);
8156     }
8157   }
8158   return true;
8159 }
8160 
8161 // LDRSH (register) calculates an address from a base register value and an
8162 // offset register value, loads a halfword
8163 // from memory, sign-extends it to form a 32-bit word, and writes it to a
8164 // register.  The offset register value can be shifted left by 0, 1, 2, or 3
8165 // bits.
EmulateLDRSHRegister(const uint32_t opcode,const ARMEncoding encoding)8166 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8167                                                  const ARMEncoding encoding) {
8168 #if 0
8169     if ConditionPassed() then
8170         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8171         offset = Shift(R[m], shift_t, shift_n, APSR.C);
8172         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8173         address = if index then offset_addr else R[n];
8174         data = MemU[address,2];
8175         if wback then R[n] = offset_addr;
8176         if UnalignedSupport() || address<0> = '0' then
8177             R[t] = SignExtend(data, 32);
8178         else // Can only apply before ARMv7
8179             R[t] = bits(32) UNKNOWN;
8180 #endif
8181 
8182   bool success = false;
8183 
8184   if (ConditionPassed(opcode)) {
8185     uint32_t t;
8186     uint32_t n;
8187     uint32_t m;
8188     bool index;
8189     bool add;
8190     bool wback;
8191     ARM_ShifterType shift_t;
8192     uint32_t shift_n;
8193 
8194     // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8195     switch (encoding) {
8196     case eEncodingT1:
8197       // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8198       // in ThumbEE";
8199       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8200       t = Bits32(opcode, 2, 0);
8201       n = Bits32(opcode, 5, 3);
8202       m = Bits32(opcode, 8, 6);
8203 
8204       // index = TRUE; add = TRUE; wback = FALSE;
8205       index = true;
8206       add = true;
8207       wback = false;
8208 
8209       // (shift_t, shift_n) = (SRType_LSL, 0);
8210       shift_t = SRType_LSL;
8211       shift_n = 0;
8212 
8213       break;
8214 
8215     case eEncodingT2:
8216       // if Rn == '1111' then SEE LDRSH (literal);
8217       // if Rt == '1111' then SEE "Unallocated memory hints";
8218       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8219       t = Bits32(opcode, 15, 12);
8220       n = Bits32(opcode, 19, 16);
8221       m = Bits32(opcode, 3, 0);
8222 
8223       // index = TRUE; add = TRUE; wback = FALSE;
8224       index = true;
8225       add = true;
8226       wback = false;
8227 
8228       // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8229       shift_t = SRType_LSL;
8230       shift_n = Bits32(opcode, 5, 4);
8231 
8232       // if t == 13 || BadReg(m) then UNPREDICTABLE;
8233       if ((t == 13) || BadReg(m))
8234         return false;
8235 
8236       break;
8237 
8238     case eEncodingA1:
8239       // if P == '0' && W == '1' then SEE LDRSHT;
8240       // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8241       t = Bits32(opcode, 15, 12);
8242       n = Bits32(opcode, 19, 16);
8243       m = Bits32(opcode, 3, 0);
8244 
8245       // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
8246       // (W == '1');
8247       index = BitIsSet(opcode, 24);
8248       add = BitIsSet(opcode, 23);
8249       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8250 
8251       // (shift_t, shift_n) = (SRType_LSL, 0);
8252       shift_t = SRType_LSL;
8253       shift_n = 0;
8254 
8255       // if t == 15 || m == 15 then UNPREDICTABLE;
8256       if ((t == 15) || (m == 15))
8257         return false;
8258 
8259       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8260       if (wback && ((n == 15) || (n == t)))
8261         return false;
8262 
8263       break;
8264 
8265     default:
8266       return false;
8267     }
8268 
8269     uint64_t Rm =
8270         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8271     if (!success)
8272       return false;
8273 
8274     uint64_t Rn =
8275         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8276     if (!success)
8277       return false;
8278 
8279     // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8280     addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8281     if (!success)
8282       return false;
8283 
8284     addr_t offset_addr;
8285     addr_t address;
8286 
8287     // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8288     if (add)
8289       offset_addr = Rn + offset;
8290     else
8291       offset_addr = Rn - offset;
8292 
8293     // address = if index then offset_addr else R[n];
8294     if (index)
8295       address = offset_addr;
8296     else
8297       address = Rn;
8298 
8299     // data = MemU[address,2];
8300     RegisterInfo base_reg;
8301     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8302 
8303     RegisterInfo offset_reg;
8304     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8305 
8306     EmulateInstruction::Context context;
8307     context.type = eContextRegisterLoad;
8308     context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8309 
8310     uint64_t data = MemURead(context, address, 2, 0, &success);
8311     if (!success)
8312       return false;
8313 
8314     // if wback then R[n] = offset_addr;
8315     if (wback) {
8316       context.type = eContextAdjustBaseRegister;
8317       context.SetAddress(offset_addr);
8318       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8319                                  offset_addr))
8320         return false;
8321     }
8322 
8323     // if UnalignedSupport() || address<0> = '0' then
8324     if (UnalignedSupport() || BitIsClear(address, 0)) {
8325       // R[t] = SignExtend(data, 32);
8326       context.type = eContextRegisterLoad;
8327       context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8328 
8329       int64_t signed_data = llvm::SignExtend64<16>(data);
8330       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8331                                  (uint64_t)signed_data))
8332         return false;
8333     } else // Can only apply before ARMv7
8334     {
8335       // R[t] = bits(32) UNKNOWN;
8336       WriteBits32Unknown(t);
8337     }
8338   }
8339   return true;
8340 }
8341 
8342 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8343 // writes the result to the destination
8344 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8345 // extracting the 8-bit value.
EmulateSXTB(const uint32_t opcode,const ARMEncoding encoding)8346 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8347                                         const ARMEncoding encoding) {
8348 #if 0
8349     if ConditionPassed() then
8350         EncodingSpecificOperations();
8351         rotated = ROR(R[m], rotation);
8352         R[d] = SignExtend(rotated<7:0>, 32);
8353 #endif
8354 
8355   bool success = false;
8356 
8357   if (ConditionPassed(opcode)) {
8358     uint32_t d;
8359     uint32_t m;
8360     uint32_t rotation;
8361 
8362     // EncodingSpecificOperations();
8363     switch (encoding) {
8364     case eEncodingT1:
8365       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8366       d = Bits32(opcode, 2, 0);
8367       m = Bits32(opcode, 5, 3);
8368       rotation = 0;
8369 
8370       break;
8371 
8372     case eEncodingT2:
8373       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8374       d = Bits32(opcode, 11, 8);
8375       m = Bits32(opcode, 3, 0);
8376       rotation = Bits32(opcode, 5, 4) << 3;
8377 
8378       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8379       if (BadReg(d) || BadReg(m))
8380         return false;
8381 
8382       break;
8383 
8384     case eEncodingA1:
8385       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8386       d = Bits32(opcode, 15, 12);
8387       m = Bits32(opcode, 3, 0);
8388       rotation = Bits32(opcode, 11, 10) << 3;
8389 
8390       // if d == 15 || m == 15 then UNPREDICTABLE;
8391       if ((d == 15) || (m == 15))
8392         return false;
8393 
8394       break;
8395 
8396     default:
8397       return false;
8398     }
8399 
8400     uint64_t Rm =
8401         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8402     if (!success)
8403       return false;
8404 
8405     // rotated = ROR(R[m], rotation);
8406     uint64_t rotated = ROR(Rm, rotation, &success);
8407     if (!success)
8408       return false;
8409 
8410     // R[d] = SignExtend(rotated<7:0>, 32);
8411     int64_t data = llvm::SignExtend64<8>(rotated);
8412 
8413     RegisterInfo source_reg;
8414     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8415 
8416     EmulateInstruction::Context context;
8417     context.type = eContextRegisterLoad;
8418     context.SetRegister(source_reg);
8419 
8420     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8421                                (uint64_t)data))
8422       return false;
8423   }
8424   return true;
8425 }
8426 
8427 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8428 // writes the result to the destination
8429 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8430 // extracting the 16-bit value.
EmulateSXTH(const uint32_t opcode,const ARMEncoding encoding)8431 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8432                                         const ARMEncoding encoding) {
8433 #if 0
8434     if ConditionPassed() then
8435         EncodingSpecificOperations();
8436         rotated = ROR(R[m], rotation);
8437         R[d] = SignExtend(rotated<15:0>, 32);
8438 #endif
8439 
8440   bool success = false;
8441 
8442   if (ConditionPassed(opcode)) {
8443     uint32_t d;
8444     uint32_t m;
8445     uint32_t rotation;
8446 
8447     // EncodingSpecificOperations();
8448     switch (encoding) {
8449     case eEncodingT1:
8450       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8451       d = Bits32(opcode, 2, 0);
8452       m = Bits32(opcode, 5, 3);
8453       rotation = 0;
8454 
8455       break;
8456 
8457     case eEncodingT2:
8458       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8459       d = Bits32(opcode, 11, 8);
8460       m = Bits32(opcode, 3, 0);
8461       rotation = Bits32(opcode, 5, 4) << 3;
8462 
8463       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8464       if (BadReg(d) || BadReg(m))
8465         return false;
8466 
8467       break;
8468 
8469     case eEncodingA1:
8470       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8471       d = Bits32(opcode, 15, 12);
8472       m = Bits32(opcode, 3, 0);
8473       rotation = Bits32(opcode, 11, 10) << 3;
8474 
8475       // if d == 15 || m == 15 then UNPREDICTABLE;
8476       if ((d == 15) || (m == 15))
8477         return false;
8478 
8479       break;
8480 
8481     default:
8482       return false;
8483     }
8484 
8485     uint64_t Rm =
8486         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8487     if (!success)
8488       return false;
8489 
8490     // rotated = ROR(R[m], rotation);
8491     uint64_t rotated = ROR(Rm, rotation, &success);
8492     if (!success)
8493       return false;
8494 
8495     // R[d] = SignExtend(rotated<15:0>, 32);
8496     RegisterInfo source_reg;
8497     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8498 
8499     EmulateInstruction::Context context;
8500     context.type = eContextRegisterLoad;
8501     context.SetRegister(source_reg);
8502 
8503     int64_t data = llvm::SignExtend64<16>(rotated);
8504     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8505                                (uint64_t)data))
8506       return false;
8507   }
8508 
8509   return true;
8510 }
8511 
8512 // UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and
8513 // writes the result to the destination
8514 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8515 // extracting the 8-bit value.
EmulateUXTB(const uint32_t opcode,const ARMEncoding encoding)8516 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8517                                         const ARMEncoding encoding) {
8518 #if 0
8519     if ConditionPassed() then
8520         EncodingSpecificOperations();
8521         rotated = ROR(R[m], rotation);
8522         R[d] = ZeroExtend(rotated<7:0>, 32);
8523 #endif
8524 
8525   bool success = false;
8526 
8527   if (ConditionPassed(opcode)) {
8528     uint32_t d;
8529     uint32_t m;
8530     uint32_t rotation;
8531 
8532     // EncodingSpecificOperations();
8533     switch (encoding) {
8534     case eEncodingT1:
8535       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8536       d = Bits32(opcode, 2, 0);
8537       m = Bits32(opcode, 5, 3);
8538       rotation = 0;
8539 
8540       break;
8541 
8542     case eEncodingT2:
8543       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8544       d = Bits32(opcode, 11, 8);
8545       m = Bits32(opcode, 3, 0);
8546       rotation = Bits32(opcode, 5, 4) << 3;
8547 
8548       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8549       if (BadReg(d) || BadReg(m))
8550         return false;
8551 
8552       break;
8553 
8554     case eEncodingA1:
8555       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8556       d = Bits32(opcode, 15, 12);
8557       m = Bits32(opcode, 3, 0);
8558       rotation = Bits32(opcode, 11, 10) << 3;
8559 
8560       // if d == 15 || m == 15 then UNPREDICTABLE;
8561       if ((d == 15) || (m == 15))
8562         return false;
8563 
8564       break;
8565 
8566     default:
8567       return false;
8568     }
8569 
8570     uint64_t Rm =
8571         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8572     if (!success)
8573       return false;
8574 
8575     // rotated = ROR(R[m], rotation);
8576     uint64_t rotated = ROR(Rm, rotation, &success);
8577     if (!success)
8578       return false;
8579 
8580     // R[d] = ZeroExtend(rotated<7:0>, 32);
8581     RegisterInfo source_reg;
8582     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8583 
8584     EmulateInstruction::Context context;
8585     context.type = eContextRegisterLoad;
8586     context.SetRegister(source_reg);
8587 
8588     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8589                                Bits32(rotated, 7, 0)))
8590       return false;
8591   }
8592   return true;
8593 }
8594 
8595 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8596 // writes the result to the destination
8597 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8598 // extracting the 16-bit value.
EmulateUXTH(const uint32_t opcode,const ARMEncoding encoding)8599 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8600                                         const ARMEncoding encoding) {
8601 #if 0
8602     if ConditionPassed() then
8603         EncodingSpecificOperations();
8604         rotated = ROR(R[m], rotation);
8605         R[d] = ZeroExtend(rotated<15:0>, 32);
8606 #endif
8607 
8608   bool success = false;
8609 
8610   if (ConditionPassed(opcode)) {
8611     uint32_t d;
8612     uint32_t m;
8613     uint32_t rotation;
8614 
8615     switch (encoding) {
8616     case eEncodingT1:
8617       // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8618       d = Bits32(opcode, 2, 0);
8619       m = Bits32(opcode, 5, 3);
8620       rotation = 0;
8621 
8622       break;
8623 
8624     case eEncodingT2:
8625       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8626       d = Bits32(opcode, 11, 8);
8627       m = Bits32(opcode, 3, 0);
8628       rotation = Bits32(opcode, 5, 4) << 3;
8629 
8630       // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8631       if (BadReg(d) || BadReg(m))
8632         return false;
8633 
8634       break;
8635 
8636     case eEncodingA1:
8637       // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8638       d = Bits32(opcode, 15, 12);
8639       m = Bits32(opcode, 3, 0);
8640       rotation = Bits32(opcode, 11, 10) << 3;
8641 
8642       // if d == 15 || m == 15 then UNPREDICTABLE;
8643       if ((d == 15) || (m == 15))
8644         return false;
8645 
8646       break;
8647 
8648     default:
8649       return false;
8650     }
8651 
8652     uint64_t Rm =
8653         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8654     if (!success)
8655       return false;
8656 
8657     // rotated = ROR(R[m], rotation);
8658     uint64_t rotated = ROR(Rm, rotation, &success);
8659     if (!success)
8660       return false;
8661 
8662     // R[d] = ZeroExtend(rotated<15:0>, 32);
8663     RegisterInfo source_reg;
8664     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8665 
8666     EmulateInstruction::Context context;
8667     context.type = eContextRegisterLoad;
8668     context.SetRegister(source_reg);
8669 
8670     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8671                                Bits32(rotated, 15, 0)))
8672       return false;
8673   }
8674   return true;
8675 }
8676 
8677 // RFE (Return From Exception) loads the PC and the CPSR from the word at the
8678 // specified address and the following
8679 // word respectively.
EmulateRFE(const uint32_t opcode,const ARMEncoding encoding)8680 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8681                                        const ARMEncoding encoding) {
8682 #if 0
8683     if ConditionPassed() then
8684         EncodingSpecificOperations();
8685         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8686             UNPREDICTABLE;
8687         else
8688             address = if increment then R[n] else R[n]-8;
8689             if wordhigher then address = address+4;
8690             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8691             BranchWritePC(MemA[address,4]);
8692             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8693 #endif
8694 
8695   bool success = false;
8696 
8697   if (ConditionPassed(opcode)) {
8698     uint32_t n;
8699     bool wback;
8700     bool increment;
8701     bool wordhigher;
8702 
8703     // EncodingSpecificOperations();
8704     switch (encoding) {
8705     case eEncodingT1:
8706       // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8707       // FALSE;
8708       n = Bits32(opcode, 19, 16);
8709       wback = BitIsSet(opcode, 21);
8710       increment = false;
8711       wordhigher = false;
8712 
8713       // if n == 15 then UNPREDICTABLE;
8714       if (n == 15)
8715         return false;
8716 
8717       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8718       if (InITBlock() && !LastInITBlock())
8719         return false;
8720 
8721       break;
8722 
8723     case eEncodingT2:
8724       // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8725       n = Bits32(opcode, 19, 16);
8726       wback = BitIsSet(opcode, 21);
8727       increment = true;
8728       wordhigher = false;
8729 
8730       // if n == 15 then UNPREDICTABLE;
8731       if (n == 15)
8732         return false;
8733 
8734       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8735       if (InITBlock() && !LastInITBlock())
8736         return false;
8737 
8738       break;
8739 
8740     case eEncodingA1:
8741       // n = UInt(Rn);
8742       n = Bits32(opcode, 19, 16);
8743 
8744       // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8745       wback = BitIsSet(opcode, 21);
8746       increment = BitIsSet(opcode, 23);
8747       wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8748 
8749       // if n == 15 then UNPREDICTABLE;
8750       if (n == 15)
8751         return false;
8752 
8753       break;
8754 
8755     default:
8756       return false;
8757     }
8758 
8759     // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8760     // then
8761     if (!CurrentModeIsPrivileged())
8762       // UNPREDICTABLE;
8763       return false;
8764     else {
8765       uint64_t Rn =
8766           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8767       if (!success)
8768         return false;
8769 
8770       addr_t address;
8771       // address = if increment then R[n] else R[n]-8;
8772       if (increment)
8773         address = Rn;
8774       else
8775         address = Rn - 8;
8776 
8777       // if wordhigher then address = address+4;
8778       if (wordhigher)
8779         address = address + 4;
8780 
8781       // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8782       RegisterInfo base_reg;
8783       GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8784 
8785       EmulateInstruction::Context context;
8786       context.type = eContextReturnFromException;
8787       context.SetRegisterPlusOffset(base_reg, address - Rn);
8788 
8789       uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8790       if (!success)
8791         return false;
8792 
8793       CPSRWriteByInstr(data, 15, true);
8794 
8795       // BranchWritePC(MemA[address,4]);
8796       uint64_t data2 = MemARead(context, address, 4, 0, &success);
8797       if (!success)
8798         return false;
8799 
8800       BranchWritePC(context, data2);
8801 
8802       // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8803       if (wback) {
8804         context.type = eContextAdjustBaseRegister;
8805         if (increment) {
8806           context.SetOffset(8);
8807           if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8808                                      Rn + 8))
8809             return false;
8810         } else {
8811           context.SetOffset(-8);
8812           if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8813                                      Rn - 8))
8814             return false;
8815         }
8816       } // if wback
8817     }
8818   } // if ConditionPassed()
8819   return true;
8820 }
8821 
8822 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8823 // register value and an immediate value, and writes the result to the
8824 // destination register.  It can optionally update the condition flags based on
8825 // the result.
EmulateEORImm(const uint32_t opcode,const ARMEncoding encoding)8826 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8827                                           const ARMEncoding encoding) {
8828 #if 0
8829     // ARM pseudo code...
8830     if ConditionPassed() then
8831         EncodingSpecificOperations();
8832         result = R[n] EOR imm32;
8833         if d == 15 then         // Can only occur for ARM encoding
8834             ALUWritePC(result); // setflags is always FALSE here
8835         else
8836             R[d] = result;
8837             if setflags then
8838                 APSR.N = result<31>;
8839                 APSR.Z = IsZeroBit(result);
8840                 APSR.C = carry;
8841                 // APSR.V unchanged
8842 #endif
8843 
8844   bool success = false;
8845 
8846   if (ConditionPassed(opcode)) {
8847     uint32_t Rd, Rn;
8848     uint32_t
8849         imm32; // the immediate value to be ORed to the value obtained from Rn
8850     bool setflags;
8851     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8852     switch (encoding) {
8853     case eEncodingT1:
8854       Rd = Bits32(opcode, 11, 8);
8855       Rn = Bits32(opcode, 19, 16);
8856       setflags = BitIsSet(opcode, 20);
8857       imm32 = ThumbExpandImm_C(
8858           opcode, APSR_C,
8859           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8860       // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8861       if (Rd == 15 && setflags)
8862         return EmulateTEQImm(opcode, eEncodingT1);
8863       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8864         return false;
8865       break;
8866     case eEncodingA1:
8867       Rd = Bits32(opcode, 15, 12);
8868       Rn = Bits32(opcode, 19, 16);
8869       setflags = BitIsSet(opcode, 20);
8870       imm32 =
8871           ARMExpandImm_C(opcode, APSR_C,
8872                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8873 
8874       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8875       // instructions;
8876       if (Rd == 15 && setflags)
8877         return EmulateSUBSPcLrEtc(opcode, encoding);
8878       break;
8879     default:
8880       return false;
8881     }
8882 
8883     // Read the first operand.
8884     uint32_t val1 = ReadCoreReg(Rn, &success);
8885     if (!success)
8886       return false;
8887 
8888     uint32_t result = val1 ^ imm32;
8889 
8890     EmulateInstruction::Context context;
8891     context.type = EmulateInstruction::eContextImmediate;
8892     context.SetNoArgs();
8893 
8894     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8895       return false;
8896   }
8897   return true;
8898 }
8899 
8900 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8901 // register value and an optionally-shifted register value, and writes the
8902 // result to the destination register. It can optionally update the condition
8903 // flags based on the result.
EmulateEORReg(const uint32_t opcode,const ARMEncoding encoding)8904 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8905                                           const ARMEncoding encoding) {
8906 #if 0
8907     // ARM pseudo code...
8908     if ConditionPassed() then
8909         EncodingSpecificOperations();
8910         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8911         result = R[n] EOR shifted;
8912         if d == 15 then         // Can only occur for ARM encoding
8913             ALUWritePC(result); // setflags is always FALSE here
8914         else
8915             R[d] = result;
8916             if setflags then
8917                 APSR.N = result<31>;
8918                 APSR.Z = IsZeroBit(result);
8919                 APSR.C = carry;
8920                 // APSR.V unchanged
8921 #endif
8922 
8923   bool success = false;
8924 
8925   if (ConditionPassed(opcode)) {
8926     uint32_t Rd, Rn, Rm;
8927     ARM_ShifterType shift_t;
8928     uint32_t shift_n; // the shift applied to the value read from Rm
8929     bool setflags;
8930     uint32_t carry;
8931     switch (encoding) {
8932     case eEncodingT1:
8933       Rd = Rn = Bits32(opcode, 2, 0);
8934       Rm = Bits32(opcode, 5, 3);
8935       setflags = !InITBlock();
8936       shift_t = SRType_LSL;
8937       shift_n = 0;
8938       break;
8939     case eEncodingT2:
8940       Rd = Bits32(opcode, 11, 8);
8941       Rn = Bits32(opcode, 19, 16);
8942       Rm = Bits32(opcode, 3, 0);
8943       setflags = BitIsSet(opcode, 20);
8944       shift_n = DecodeImmShiftThumb(opcode, shift_t);
8945       // if Rd == '1111' && S == '1' then SEE TEQ (register);
8946       if (Rd == 15 && setflags)
8947         return EmulateTEQReg(opcode, eEncodingT1);
8948       if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8949         return false;
8950       break;
8951     case eEncodingA1:
8952       Rd = Bits32(opcode, 15, 12);
8953       Rn = Bits32(opcode, 19, 16);
8954       Rm = Bits32(opcode, 3, 0);
8955       setflags = BitIsSet(opcode, 20);
8956       shift_n = DecodeImmShiftARM(opcode, shift_t);
8957 
8958       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8959       // instructions;
8960       if (Rd == 15 && setflags)
8961         return EmulateSUBSPcLrEtc(opcode, encoding);
8962       break;
8963     default:
8964       return false;
8965     }
8966 
8967     // Read the first operand.
8968     uint32_t val1 = ReadCoreReg(Rn, &success);
8969     if (!success)
8970       return false;
8971 
8972     // Read the second operand.
8973     uint32_t val2 = ReadCoreReg(Rm, &success);
8974     if (!success)
8975       return false;
8976 
8977     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8978     if (!success)
8979       return false;
8980     uint32_t result = val1 ^ shifted;
8981 
8982     EmulateInstruction::Context context;
8983     context.type = EmulateInstruction::eContextImmediate;
8984     context.SetNoArgs();
8985 
8986     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8987       return false;
8988   }
8989   return true;
8990 }
8991 
8992 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8993 // and an immediate value, and writes the result to the destination register.
8994 // It can optionally update the condition flags based on the result.
EmulateORRImm(const uint32_t opcode,const ARMEncoding encoding)8995 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8996                                           const ARMEncoding encoding) {
8997 #if 0
8998     // ARM pseudo code...
8999     if ConditionPassed() then
9000         EncodingSpecificOperations();
9001         result = R[n] OR imm32;
9002         if d == 15 then         // Can only occur for ARM encoding
9003             ALUWritePC(result); // setflags is always FALSE here
9004         else
9005             R[d] = result;
9006             if setflags then
9007                 APSR.N = result<31>;
9008                 APSR.Z = IsZeroBit(result);
9009                 APSR.C = carry;
9010                 // APSR.V unchanged
9011 #endif
9012 
9013   bool success = false;
9014 
9015   if (ConditionPassed(opcode)) {
9016     uint32_t Rd, Rn;
9017     uint32_t
9018         imm32; // the immediate value to be ORed to the value obtained from Rn
9019     bool setflags;
9020     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9021     switch (encoding) {
9022     case eEncodingT1:
9023       Rd = Bits32(opcode, 11, 8);
9024       Rn = Bits32(opcode, 19, 16);
9025       setflags = BitIsSet(opcode, 20);
9026       imm32 = ThumbExpandImm_C(
9027           opcode, APSR_C,
9028           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9029       // if Rn == '1111' then SEE MOV (immediate);
9030       if (Rn == 15)
9031         return EmulateMOVRdImm(opcode, eEncodingT2);
9032       if (BadReg(Rd) || Rn == 13)
9033         return false;
9034       break;
9035     case eEncodingA1:
9036       Rd = Bits32(opcode, 15, 12);
9037       Rn = Bits32(opcode, 19, 16);
9038       setflags = BitIsSet(opcode, 20);
9039       imm32 =
9040           ARMExpandImm_C(opcode, APSR_C,
9041                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9042 
9043       if (Rd == 15 && setflags)
9044         return EmulateSUBSPcLrEtc(opcode, encoding);
9045       break;
9046     default:
9047       return false;
9048     }
9049 
9050     // Read the first operand.
9051     uint32_t val1 = ReadCoreReg(Rn, &success);
9052     if (!success)
9053       return false;
9054 
9055     uint32_t result = val1 | imm32;
9056 
9057     EmulateInstruction::Context context;
9058     context.type = EmulateInstruction::eContextImmediate;
9059     context.SetNoArgs();
9060 
9061     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9062       return false;
9063   }
9064   return true;
9065 }
9066 
9067 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9068 // and an optionally-shifted register value, and writes the result to the
9069 // destination register.  It can optionally update the condition flags based on
9070 // the result.
EmulateORRReg(const uint32_t opcode,const ARMEncoding encoding)9071 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9072                                           const ARMEncoding encoding) {
9073 #if 0
9074     // ARM pseudo code...
9075     if ConditionPassed() then
9076         EncodingSpecificOperations();
9077         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9078         result = R[n] OR shifted;
9079         if d == 15 then         // Can only occur for ARM encoding
9080             ALUWritePC(result); // setflags is always FALSE here
9081         else
9082             R[d] = result;
9083             if setflags then
9084                 APSR.N = result<31>;
9085                 APSR.Z = IsZeroBit(result);
9086                 APSR.C = carry;
9087                 // APSR.V unchanged
9088 #endif
9089 
9090   bool success = false;
9091 
9092   if (ConditionPassed(opcode)) {
9093     uint32_t Rd, Rn, Rm;
9094     ARM_ShifterType shift_t;
9095     uint32_t shift_n; // the shift applied to the value read from Rm
9096     bool setflags;
9097     uint32_t carry;
9098     switch (encoding) {
9099     case eEncodingT1:
9100       Rd = Rn = Bits32(opcode, 2, 0);
9101       Rm = Bits32(opcode, 5, 3);
9102       setflags = !InITBlock();
9103       shift_t = SRType_LSL;
9104       shift_n = 0;
9105       break;
9106     case eEncodingT2:
9107       Rd = Bits32(opcode, 11, 8);
9108       Rn = Bits32(opcode, 19, 16);
9109       Rm = Bits32(opcode, 3, 0);
9110       setflags = BitIsSet(opcode, 20);
9111       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9112       // if Rn == '1111' then SEE MOV (register);
9113       if (Rn == 15)
9114         return EmulateMOVRdRm(opcode, eEncodingT3);
9115       if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9116         return false;
9117       break;
9118     case eEncodingA1:
9119       Rd = Bits32(opcode, 15, 12);
9120       Rn = Bits32(opcode, 19, 16);
9121       Rm = Bits32(opcode, 3, 0);
9122       setflags = BitIsSet(opcode, 20);
9123       shift_n = DecodeImmShiftARM(opcode, shift_t);
9124 
9125       if (Rd == 15 && setflags)
9126         return EmulateSUBSPcLrEtc(opcode, encoding);
9127       break;
9128     default:
9129       return false;
9130     }
9131 
9132     // Read the first operand.
9133     uint32_t val1 = ReadCoreReg(Rn, &success);
9134     if (!success)
9135       return false;
9136 
9137     // Read the second operand.
9138     uint32_t val2 = ReadCoreReg(Rm, &success);
9139     if (!success)
9140       return false;
9141 
9142     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9143     if (!success)
9144       return false;
9145     uint32_t result = val1 | shifted;
9146 
9147     EmulateInstruction::Context context;
9148     context.type = EmulateInstruction::eContextImmediate;
9149     context.SetNoArgs();
9150 
9151     if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9152       return false;
9153   }
9154   return true;
9155 }
9156 
9157 // Reverse Subtract (immediate) subtracts a register value from an immediate
9158 // value, and writes the result to the destination register. It can optionally
9159 // update the condition flags based on the result.
EmulateRSBImm(const uint32_t opcode,const ARMEncoding encoding)9160 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9161                                           const ARMEncoding encoding) {
9162 #if 0
9163     // ARM pseudo code...
9164     if ConditionPassed() then
9165         EncodingSpecificOperations();
9166         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9167         if d == 15 then         // Can only occur for ARM encoding
9168             ALUWritePC(result); // setflags is always FALSE here
9169         else
9170             R[d] = result;
9171             if setflags then
9172                 APSR.N = result<31>;
9173                 APSR.Z = IsZeroBit(result);
9174                 APSR.C = carry;
9175                 APSR.V = overflow;
9176 #endif
9177 
9178   bool success = false;
9179 
9180   uint32_t Rd; // the destination register
9181   uint32_t Rn; // the first operand
9182   bool setflags;
9183   uint32_t
9184       imm32; // the immediate value to be added to the value obtained from Rn
9185   switch (encoding) {
9186   case eEncodingT1:
9187     Rd = Bits32(opcode, 2, 0);
9188     Rn = Bits32(opcode, 5, 3);
9189     setflags = !InITBlock();
9190     imm32 = 0;
9191     break;
9192   case eEncodingT2:
9193     Rd = Bits32(opcode, 11, 8);
9194     Rn = Bits32(opcode, 19, 16);
9195     setflags = BitIsSet(opcode, 20);
9196     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9197     if (BadReg(Rd) || BadReg(Rn))
9198       return false;
9199     break;
9200   case eEncodingA1:
9201     Rd = Bits32(opcode, 15, 12);
9202     Rn = Bits32(opcode, 19, 16);
9203     setflags = BitIsSet(opcode, 20);
9204     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9205 
9206     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9207     // instructions;
9208     if (Rd == 15 && setflags)
9209       return EmulateSUBSPcLrEtc(opcode, encoding);
9210     break;
9211   default:
9212     return false;
9213   }
9214   // Read the register value from the operand register Rn.
9215   uint32_t reg_val = ReadCoreReg(Rn, &success);
9216   if (!success)
9217     return false;
9218 
9219   AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9220 
9221   EmulateInstruction::Context context;
9222   context.type = EmulateInstruction::eContextImmediate;
9223   context.SetNoArgs();
9224 
9225   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9226                                    res.carry_out, res.overflow);
9227 }
9228 
9229 // Reverse Subtract (register) subtracts a register value from an optionally-
9230 // shifted register value, and writes the result to the destination register.
9231 // It can optionally update the condition flags based on the result.
EmulateRSBReg(const uint32_t opcode,const ARMEncoding encoding)9232 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9233                                           const ARMEncoding encoding) {
9234 #if 0
9235     // ARM pseudo code...
9236     if ConditionPassed() then
9237         EncodingSpecificOperations();
9238         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9239         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9240         if d == 15 then         // Can only occur for ARM encoding
9241             ALUWritePC(result); // setflags is always FALSE here
9242         else
9243             R[d] = result;
9244             if setflags then
9245                 APSR.N = result<31>;
9246                 APSR.Z = IsZeroBit(result);
9247                 APSR.C = carry;
9248                 APSR.V = overflow;
9249 #endif
9250 
9251   bool success = false;
9252 
9253   uint32_t Rd; // the destination register
9254   uint32_t Rn; // the first operand
9255   uint32_t Rm; // the second operand
9256   bool setflags;
9257   ARM_ShifterType shift_t;
9258   uint32_t shift_n; // the shift applied to the value read from Rm
9259   switch (encoding) {
9260   case eEncodingT1:
9261     Rd = Bits32(opcode, 11, 8);
9262     Rn = Bits32(opcode, 19, 16);
9263     Rm = Bits32(opcode, 3, 0);
9264     setflags = BitIsSet(opcode, 20);
9265     shift_n = DecodeImmShiftThumb(opcode, shift_t);
9266     // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9267     if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9268       return false;
9269     break;
9270   case eEncodingA1:
9271     Rd = Bits32(opcode, 15, 12);
9272     Rn = Bits32(opcode, 19, 16);
9273     Rm = Bits32(opcode, 3, 0);
9274     setflags = BitIsSet(opcode, 20);
9275     shift_n = DecodeImmShiftARM(opcode, shift_t);
9276 
9277     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9278     // instructions;
9279     if (Rd == 15 && setflags)
9280       return EmulateSUBSPcLrEtc(opcode, encoding);
9281     break;
9282   default:
9283     return false;
9284   }
9285   // Read the register value from register Rn.
9286   uint32_t val1 = ReadCoreReg(Rn, &success);
9287   if (!success)
9288     return false;
9289 
9290   // Read the register value from register Rm.
9291   uint32_t val2 = ReadCoreReg(Rm, &success);
9292   if (!success)
9293     return false;
9294 
9295   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9296   if (!success)
9297     return false;
9298   AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9299 
9300   EmulateInstruction::Context context;
9301   context.type = EmulateInstruction::eContextImmediate;
9302   context.SetNoArgs();
9303   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9304                                    res.carry_out, res.overflow);
9305 }
9306 
9307 // Reverse Subtract with Carry (immediate) subtracts a register value and the
9308 // value of NOT (Carry flag) from an immediate value, and writes the result to
9309 // the destination register. It can optionally update the condition flags based
9310 // on the result.
EmulateRSCImm(const uint32_t opcode,const ARMEncoding encoding)9311 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9312                                           const ARMEncoding encoding) {
9313 #if 0
9314     // ARM pseudo code...
9315     if ConditionPassed() then
9316         EncodingSpecificOperations();
9317         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9318         if d == 15 then
9319             ALUWritePC(result); // setflags is always FALSE here
9320         else
9321             R[d] = result;
9322             if setflags then
9323                 APSR.N = result<31>;
9324                 APSR.Z = IsZeroBit(result);
9325                 APSR.C = carry;
9326                 APSR.V = overflow;
9327 #endif
9328 
9329   bool success = false;
9330 
9331   uint32_t Rd; // the destination register
9332   uint32_t Rn; // the first operand
9333   bool setflags;
9334   uint32_t
9335       imm32; // the immediate value to be added to the value obtained from Rn
9336   switch (encoding) {
9337   case eEncodingA1:
9338     Rd = Bits32(opcode, 15, 12);
9339     Rn = Bits32(opcode, 19, 16);
9340     setflags = BitIsSet(opcode, 20);
9341     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9342 
9343     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9344     // instructions;
9345     if (Rd == 15 && setflags)
9346       return EmulateSUBSPcLrEtc(opcode, encoding);
9347     break;
9348   default:
9349     return false;
9350   }
9351   // Read the register value from the operand register Rn.
9352   uint32_t reg_val = ReadCoreReg(Rn, &success);
9353   if (!success)
9354     return false;
9355 
9356   AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9357 
9358   EmulateInstruction::Context context;
9359   context.type = EmulateInstruction::eContextImmediate;
9360   context.SetNoArgs();
9361 
9362   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9363                                    res.carry_out, res.overflow);
9364 }
9365 
9366 // Reverse Subtract with Carry (register) subtracts a register value and the
9367 // value of NOT (Carry flag) from an optionally-shifted register value, and
9368 // writes the result to the destination register. It can optionally update the
9369 // condition flags based on the result.
EmulateRSCReg(const uint32_t opcode,const ARMEncoding encoding)9370 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9371                                           const ARMEncoding encoding) {
9372 #if 0
9373     // ARM pseudo code...
9374     if ConditionPassed() then
9375         EncodingSpecificOperations();
9376         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9377         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9378         if d == 15 then
9379             ALUWritePC(result); // setflags is always FALSE here
9380         else
9381             R[d] = result;
9382             if setflags then
9383                 APSR.N = result<31>;
9384                 APSR.Z = IsZeroBit(result);
9385                 APSR.C = carry;
9386                 APSR.V = overflow;
9387 #endif
9388 
9389   bool success = false;
9390 
9391   uint32_t Rd; // the destination register
9392   uint32_t Rn; // the first operand
9393   uint32_t Rm; // the second operand
9394   bool setflags;
9395   ARM_ShifterType shift_t;
9396   uint32_t shift_n; // the shift applied to the value read from Rm
9397   switch (encoding) {
9398   case eEncodingA1:
9399     Rd = Bits32(opcode, 15, 12);
9400     Rn = Bits32(opcode, 19, 16);
9401     Rm = Bits32(opcode, 3, 0);
9402     setflags = BitIsSet(opcode, 20);
9403     shift_n = DecodeImmShiftARM(opcode, shift_t);
9404 
9405     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9406     // instructions;
9407     if (Rd == 15 && setflags)
9408       return EmulateSUBSPcLrEtc(opcode, encoding);
9409     break;
9410   default:
9411     return false;
9412   }
9413   // Read the register value from register Rn.
9414   uint32_t val1 = ReadCoreReg(Rn, &success);
9415   if (!success)
9416     return false;
9417 
9418   // Read the register value from register Rm.
9419   uint32_t val2 = ReadCoreReg(Rm, &success);
9420   if (!success)
9421     return false;
9422 
9423   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9424   if (!success)
9425     return false;
9426   AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9427 
9428   EmulateInstruction::Context context;
9429   context.type = EmulateInstruction::eContextImmediate;
9430   context.SetNoArgs();
9431   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9432                                    res.carry_out, res.overflow);
9433 }
9434 
9435 // Subtract with Carry (immediate) subtracts an immediate value and the value
9436 // of
9437 // NOT (Carry flag) from a register value, and writes the result to the
9438 // destination register.
9439 // It can optionally update the condition flags based on the result.
EmulateSBCImm(const uint32_t opcode,const ARMEncoding encoding)9440 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9441                                           const ARMEncoding encoding) {
9442 #if 0
9443     // ARM pseudo code...
9444     if ConditionPassed() then
9445         EncodingSpecificOperations();
9446         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9447         if d == 15 then         // Can only occur for ARM encoding
9448             ALUWritePC(result); // setflags is always FALSE here
9449         else
9450             R[d] = result;
9451             if setflags then
9452                 APSR.N = result<31>;
9453                 APSR.Z = IsZeroBit(result);
9454                 APSR.C = carry;
9455                 APSR.V = overflow;
9456 #endif
9457 
9458   bool success = false;
9459 
9460   uint32_t Rd; // the destination register
9461   uint32_t Rn; // the first operand
9462   bool setflags;
9463   uint32_t
9464       imm32; // the immediate value to be added to the value obtained from Rn
9465   switch (encoding) {
9466   case eEncodingT1:
9467     Rd = Bits32(opcode, 11, 8);
9468     Rn = Bits32(opcode, 19, 16);
9469     setflags = BitIsSet(opcode, 20);
9470     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9471     if (BadReg(Rd) || BadReg(Rn))
9472       return false;
9473     break;
9474   case eEncodingA1:
9475     Rd = Bits32(opcode, 15, 12);
9476     Rn = Bits32(opcode, 19, 16);
9477     setflags = BitIsSet(opcode, 20);
9478     imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9479 
9480     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9481     // instructions;
9482     if (Rd == 15 && setflags)
9483       return EmulateSUBSPcLrEtc(opcode, encoding);
9484     break;
9485   default:
9486     return false;
9487   }
9488   // Read the register value from the operand register Rn.
9489   uint32_t reg_val = ReadCoreReg(Rn, &success);
9490   if (!success)
9491     return false;
9492 
9493   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9494 
9495   EmulateInstruction::Context context;
9496   context.type = EmulateInstruction::eContextImmediate;
9497   context.SetNoArgs();
9498 
9499   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9500                                    res.carry_out, res.overflow);
9501 }
9502 
9503 // Subtract with Carry (register) subtracts an optionally-shifted register
9504 // value and the value of
9505 // NOT (Carry flag) from a register value, and writes the result to the
9506 // destination register.
9507 // It can optionally update the condition flags based on the result.
EmulateSBCReg(const uint32_t opcode,const ARMEncoding encoding)9508 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9509                                           const ARMEncoding encoding) {
9510 #if 0
9511     // ARM pseudo code...
9512     if ConditionPassed() then
9513         EncodingSpecificOperations();
9514         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9515         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9516         if d == 15 then         // Can only occur for ARM encoding
9517             ALUWritePC(result); // setflags is always FALSE here
9518         else
9519             R[d] = result;
9520             if setflags then
9521                 APSR.N = result<31>;
9522                 APSR.Z = IsZeroBit(result);
9523                 APSR.C = carry;
9524                 APSR.V = overflow;
9525 #endif
9526 
9527   bool success = false;
9528 
9529   uint32_t Rd; // the destination register
9530   uint32_t Rn; // the first operand
9531   uint32_t Rm; // the second operand
9532   bool setflags;
9533   ARM_ShifterType shift_t;
9534   uint32_t shift_n; // the shift applied to the value read from Rm
9535   switch (encoding) {
9536   case eEncodingT1:
9537     Rd = Rn = Bits32(opcode, 2, 0);
9538     Rm = Bits32(opcode, 5, 3);
9539     setflags = !InITBlock();
9540     shift_t = SRType_LSL;
9541     shift_n = 0;
9542     break;
9543   case eEncodingT2:
9544     Rd = Bits32(opcode, 11, 8);
9545     Rn = Bits32(opcode, 19, 16);
9546     Rm = Bits32(opcode, 3, 0);
9547     setflags = BitIsSet(opcode, 20);
9548     shift_n = DecodeImmShiftThumb(opcode, shift_t);
9549     if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9550       return false;
9551     break;
9552   case eEncodingA1:
9553     Rd = Bits32(opcode, 15, 12);
9554     Rn = Bits32(opcode, 19, 16);
9555     Rm = Bits32(opcode, 3, 0);
9556     setflags = BitIsSet(opcode, 20);
9557     shift_n = DecodeImmShiftARM(opcode, shift_t);
9558 
9559     // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9560     // instructions;
9561     if (Rd == 15 && setflags)
9562       return EmulateSUBSPcLrEtc(opcode, encoding);
9563     break;
9564   default:
9565     return false;
9566   }
9567   // Read the register value from register Rn.
9568   uint32_t val1 = ReadCoreReg(Rn, &success);
9569   if (!success)
9570     return false;
9571 
9572   // Read the register value from register Rm.
9573   uint32_t val2 = ReadCoreReg(Rm, &success);
9574   if (!success)
9575     return false;
9576 
9577   uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9578   if (!success)
9579     return false;
9580   AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9581 
9582   EmulateInstruction::Context context;
9583   context.type = EmulateInstruction::eContextImmediate;
9584   context.SetNoArgs();
9585   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9586                                    res.carry_out, res.overflow);
9587 }
9588 
9589 // This instruction subtracts an immediate value from a register value, and
9590 // writes the result to the destination register.  It can optionally update the
9591 // condition flags based on the result.
EmulateSUBImmThumb(const uint32_t opcode,const ARMEncoding encoding)9592 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9593                                                const ARMEncoding encoding) {
9594 #if 0
9595     // ARM pseudo code...
9596     if ConditionPassed() then
9597         EncodingSpecificOperations();
9598         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9599         R[d] = result;
9600         if setflags then
9601             APSR.N = result<31>;
9602             APSR.Z = IsZeroBit(result);
9603             APSR.C = carry;
9604             APSR.V = overflow;
9605 #endif
9606 
9607   bool success = false;
9608 
9609   uint32_t Rd; // the destination register
9610   uint32_t Rn; // the first operand
9611   bool setflags;
9612   uint32_t imm32; // the immediate value to be subtracted from the value
9613                   // obtained from Rn
9614   switch (encoding) {
9615   case eEncodingT1:
9616     Rd = Bits32(opcode, 2, 0);
9617     Rn = Bits32(opcode, 5, 3);
9618     setflags = !InITBlock();
9619     imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9620     break;
9621   case eEncodingT2:
9622     Rd = Rn = Bits32(opcode, 10, 8);
9623     setflags = !InITBlock();
9624     imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9625     break;
9626   case eEncodingT3:
9627     Rd = Bits32(opcode, 11, 8);
9628     Rn = Bits32(opcode, 19, 16);
9629     setflags = BitIsSet(opcode, 20);
9630     imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9631 
9632     // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9633     if (Rd == 15 && setflags)
9634       return EmulateCMPImm(opcode, eEncodingT2);
9635 
9636     // if Rn == '1101' then SEE SUB (SP minus immediate);
9637     if (Rn == 13)
9638       return EmulateSUBSPImm(opcode, eEncodingT2);
9639 
9640     // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9641     if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9642       return false;
9643     break;
9644   case eEncodingT4:
9645     Rd = Bits32(opcode, 11, 8);
9646     Rn = Bits32(opcode, 19, 16);
9647     setflags = BitIsSet(opcode, 20);
9648     imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9649 
9650     // if Rn == '1111' then SEE ADR;
9651     if (Rn == 15)
9652       return EmulateADR(opcode, eEncodingT2);
9653 
9654     // if Rn == '1101' then SEE SUB (SP minus immediate);
9655     if (Rn == 13)
9656       return EmulateSUBSPImm(opcode, eEncodingT3);
9657 
9658     if (BadReg(Rd))
9659       return false;
9660     break;
9661   default:
9662     return false;
9663   }
9664   // Read the register value from the operand register Rn.
9665   uint32_t reg_val = ReadCoreReg(Rn, &success);
9666   if (!success)
9667     return false;
9668 
9669   AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9670 
9671   EmulateInstruction::Context context;
9672   context.type = EmulateInstruction::eContextImmediate;
9673   context.SetNoArgs();
9674 
9675   return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9676                                    res.carry_out, res.overflow);
9677 }
9678 
9679 // This instruction subtracts an immediate value from a register value, and
9680 // writes the result to the destination register.  It can optionally update the
9681 // condition flags based on the result.
EmulateSUBImmARM(const uint32_t opcode,const ARMEncoding encoding)9682 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9683                                              const ARMEncoding encoding) {
9684 #if 0
9685     // ARM pseudo code...
9686     if ConditionPassed() then
9687         EncodingSpecificOperations();
9688         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9689         if d == 15 then
9690             ALUWritePC(result); // setflags is always FALSE here
9691         else
9692             R[d] = result;
9693             if setflags then
9694                 APSR.N = result<31>;
9695                 APSR.Z = IsZeroBit(result);
9696                 APSR.C = carry;
9697                 APSR.V = overflow;
9698 #endif
9699 
9700   bool success = false;
9701 
9702   if (ConditionPassed(opcode)) {
9703     uint32_t Rd; // the destination register
9704     uint32_t Rn; // the first operand
9705     bool setflags;
9706     uint32_t imm32; // the immediate value to be subtracted from the value
9707                     // obtained from Rn
9708     switch (encoding) {
9709     case eEncodingA1:
9710       Rd = Bits32(opcode, 15, 12);
9711       Rn = Bits32(opcode, 19, 16);
9712       setflags = BitIsSet(opcode, 20);
9713       imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9714 
9715       // if Rn == '1111' && S == '0' then SEE ADR;
9716       if (Rn == 15 && !setflags)
9717         return EmulateADR(opcode, eEncodingA2);
9718 
9719       // if Rn == '1101' then SEE SUB (SP minus immediate);
9720       if (Rn == 13)
9721         return EmulateSUBSPImm(opcode, eEncodingA1);
9722 
9723       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9724       // instructions;
9725       if (Rd == 15 && setflags)
9726         return EmulateSUBSPcLrEtc(opcode, encoding);
9727       break;
9728     default:
9729       return false;
9730     }
9731     // Read the register value from the operand register Rn.
9732     uint32_t reg_val = ReadCoreReg(Rn, &success);
9733     if (!success)
9734       return false;
9735 
9736     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9737 
9738     EmulateInstruction::Context context;
9739     if (Rd == 13)
9740       context.type = EmulateInstruction::eContextAdjustStackPointer;
9741     else
9742       context.type = EmulateInstruction::eContextRegisterPlusOffset;
9743 
9744     RegisterInfo dwarf_reg;
9745     GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9746     int64_t imm32_signed = imm32;
9747     context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9748 
9749     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9750                                    res.carry_out, res.overflow))
9751       return false;
9752   }
9753   return true;
9754 }
9755 
9756 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9757 // register value and an immediate value.  It updates the condition flags based
9758 // on the result, and discards the result.
EmulateTEQImm(const uint32_t opcode,const ARMEncoding encoding)9759 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9760                                           const ARMEncoding encoding) {
9761 #if 0
9762     // ARM pseudo code...
9763     if ConditionPassed() then
9764         EncodingSpecificOperations();
9765         result = R[n] EOR imm32;
9766         APSR.N = result<31>;
9767         APSR.Z = IsZeroBit(result);
9768         APSR.C = carry;
9769         // APSR.V unchanged
9770 #endif
9771 
9772   bool success = false;
9773 
9774   if (ConditionPassed(opcode)) {
9775     uint32_t Rn;
9776     uint32_t
9777         imm32; // the immediate value to be ANDed to the value obtained from Rn
9778     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9779     switch (encoding) {
9780     case eEncodingT1:
9781       Rn = Bits32(opcode, 19, 16);
9782       imm32 = ThumbExpandImm_C(
9783           opcode, APSR_C,
9784           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9785       if (BadReg(Rn))
9786         return false;
9787       break;
9788     case eEncodingA1:
9789       Rn = Bits32(opcode, 19, 16);
9790       imm32 =
9791           ARMExpandImm_C(opcode, APSR_C,
9792                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9793       break;
9794     default:
9795       return false;
9796     }
9797 
9798     // Read the first operand.
9799     uint32_t val1 = ReadCoreReg(Rn, &success);
9800     if (!success)
9801       return false;
9802 
9803     uint32_t result = val1 ^ imm32;
9804 
9805     EmulateInstruction::Context context;
9806     context.type = EmulateInstruction::eContextImmediate;
9807     context.SetNoArgs();
9808 
9809     if (!WriteFlags(context, result, carry))
9810       return false;
9811   }
9812   return true;
9813 }
9814 
9815 // Test Equivalence (register) performs a bitwise exclusive OR operation on a
9816 // register value and an optionally-shifted register value.  It updates the
9817 // condition flags based on the result, and discards the result.
EmulateTEQReg(const uint32_t opcode,const ARMEncoding encoding)9818 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9819                                           const ARMEncoding encoding) {
9820 #if 0
9821     // ARM pseudo code...
9822     if ConditionPassed() then
9823         EncodingSpecificOperations();
9824         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9825         result = R[n] EOR shifted;
9826         APSR.N = result<31>;
9827         APSR.Z = IsZeroBit(result);
9828         APSR.C = carry;
9829         // APSR.V unchanged
9830 #endif
9831 
9832   bool success = false;
9833 
9834   if (ConditionPassed(opcode)) {
9835     uint32_t Rn, Rm;
9836     ARM_ShifterType shift_t;
9837     uint32_t shift_n; // the shift applied to the value read from Rm
9838     uint32_t carry;
9839     switch (encoding) {
9840     case eEncodingT1:
9841       Rn = Bits32(opcode, 19, 16);
9842       Rm = Bits32(opcode, 3, 0);
9843       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9844       if (BadReg(Rn) || BadReg(Rm))
9845         return false;
9846       break;
9847     case eEncodingA1:
9848       Rn = Bits32(opcode, 19, 16);
9849       Rm = Bits32(opcode, 3, 0);
9850       shift_n = DecodeImmShiftARM(opcode, shift_t);
9851       break;
9852     default:
9853       return false;
9854     }
9855 
9856     // Read the first operand.
9857     uint32_t val1 = ReadCoreReg(Rn, &success);
9858     if (!success)
9859       return false;
9860 
9861     // Read the second operand.
9862     uint32_t val2 = ReadCoreReg(Rm, &success);
9863     if (!success)
9864       return false;
9865 
9866     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9867     if (!success)
9868       return false;
9869     uint32_t result = val1 ^ shifted;
9870 
9871     EmulateInstruction::Context context;
9872     context.type = EmulateInstruction::eContextImmediate;
9873     context.SetNoArgs();
9874 
9875     if (!WriteFlags(context, result, carry))
9876       return false;
9877   }
9878   return true;
9879 }
9880 
9881 // Test (immediate) performs a bitwise AND operation on a register value and an
9882 // immediate value. It updates the condition flags based on the result, and
9883 // discards the result.
EmulateTSTImm(const uint32_t opcode,const ARMEncoding encoding)9884 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9885                                           const ARMEncoding encoding) {
9886 #if 0
9887     // ARM pseudo code...
9888     if ConditionPassed() then
9889         EncodingSpecificOperations();
9890         result = R[n] AND imm32;
9891         APSR.N = result<31>;
9892         APSR.Z = IsZeroBit(result);
9893         APSR.C = carry;
9894         // APSR.V unchanged
9895 #endif
9896 
9897   bool success = false;
9898 
9899   if (ConditionPassed(opcode)) {
9900     uint32_t Rn;
9901     uint32_t
9902         imm32; // the immediate value to be ANDed to the value obtained from Rn
9903     uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9904     switch (encoding) {
9905     case eEncodingT1:
9906       Rn = Bits32(opcode, 19, 16);
9907       imm32 = ThumbExpandImm_C(
9908           opcode, APSR_C,
9909           carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9910       if (BadReg(Rn))
9911         return false;
9912       break;
9913     case eEncodingA1:
9914       Rn = Bits32(opcode, 19, 16);
9915       imm32 =
9916           ARMExpandImm_C(opcode, APSR_C,
9917                          carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9918       break;
9919     default:
9920       return false;
9921     }
9922 
9923     // Read the first operand.
9924     uint32_t val1 = ReadCoreReg(Rn, &success);
9925     if (!success)
9926       return false;
9927 
9928     uint32_t result = val1 & imm32;
9929 
9930     EmulateInstruction::Context context;
9931     context.type = EmulateInstruction::eContextImmediate;
9932     context.SetNoArgs();
9933 
9934     if (!WriteFlags(context, result, carry))
9935       return false;
9936   }
9937   return true;
9938 }
9939 
9940 // Test (register) performs a bitwise AND operation on a register value and an
9941 // optionally-shifted register value. It updates the condition flags based on
9942 // the result, and discards the result.
EmulateTSTReg(const uint32_t opcode,const ARMEncoding encoding)9943 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9944                                           const ARMEncoding encoding) {
9945 #if 0
9946     // ARM pseudo code...
9947     if ConditionPassed() then
9948         EncodingSpecificOperations();
9949         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9950         result = R[n] AND shifted;
9951         APSR.N = result<31>;
9952         APSR.Z = IsZeroBit(result);
9953         APSR.C = carry;
9954         // APSR.V unchanged
9955 #endif
9956 
9957   bool success = false;
9958 
9959   if (ConditionPassed(opcode)) {
9960     uint32_t Rn, Rm;
9961     ARM_ShifterType shift_t;
9962     uint32_t shift_n; // the shift applied to the value read from Rm
9963     uint32_t carry;
9964     switch (encoding) {
9965     case eEncodingT1:
9966       Rn = Bits32(opcode, 2, 0);
9967       Rm = Bits32(opcode, 5, 3);
9968       shift_t = SRType_LSL;
9969       shift_n = 0;
9970       break;
9971     case eEncodingT2:
9972       Rn = Bits32(opcode, 19, 16);
9973       Rm = Bits32(opcode, 3, 0);
9974       shift_n = DecodeImmShiftThumb(opcode, shift_t);
9975       if (BadReg(Rn) || BadReg(Rm))
9976         return false;
9977       break;
9978     case eEncodingA1:
9979       Rn = Bits32(opcode, 19, 16);
9980       Rm = Bits32(opcode, 3, 0);
9981       shift_n = DecodeImmShiftARM(opcode, shift_t);
9982       break;
9983     default:
9984       return false;
9985     }
9986 
9987     // Read the first operand.
9988     uint32_t val1 = ReadCoreReg(Rn, &success);
9989     if (!success)
9990       return false;
9991 
9992     // Read the second operand.
9993     uint32_t val2 = ReadCoreReg(Rm, &success);
9994     if (!success)
9995       return false;
9996 
9997     uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9998     if (!success)
9999       return false;
10000     uint32_t result = val1 & shifted;
10001 
10002     EmulateInstruction::Context context;
10003     context.type = EmulateInstruction::eContextImmediate;
10004     context.SetNoArgs();
10005 
10006     if (!WriteFlags(context, result, carry))
10007       return false;
10008   }
10009   return true;
10010 }
10011 
10012 // A8.6.216 SUB (SP minus register)
EmulateSUBSPReg(const uint32_t opcode,const ARMEncoding encoding)10013 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10014                                             const ARMEncoding encoding) {
10015 #if 0
10016     if ConditionPassed() then
10017         EncodingSpecificOperations();
10018         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10019         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10020         if d == 15 then // Can only occur for ARM encoding
10021             ALUWritePC(result); // setflags is always FALSE here
10022         else
10023             R[d] = result;
10024             if setflags then
10025                 APSR.N = result<31>;
10026                 APSR.Z = IsZeroBit(result);
10027                 APSR.C = carry;
10028                 APSR.V = overflow;
10029 #endif
10030 
10031   bool success = false;
10032 
10033   if (ConditionPassed(opcode)) {
10034     uint32_t d;
10035     uint32_t m;
10036     bool setflags;
10037     ARM_ShifterType shift_t;
10038     uint32_t shift_n;
10039 
10040     switch (encoding) {
10041     case eEncodingT1:
10042       // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10043       d = Bits32(opcode, 11, 8);
10044       m = Bits32(opcode, 3, 0);
10045       setflags = BitIsSet(opcode, 20);
10046 
10047       // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10048       shift_n = DecodeImmShiftThumb(opcode, shift_t);
10049 
10050       // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10051       // UNPREDICTABLE;
10052       if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10053         return false;
10054 
10055       // if d == 15 || BadReg(m) then UNPREDICTABLE;
10056       if ((d == 15) || BadReg(m))
10057         return false;
10058       break;
10059 
10060     case eEncodingA1:
10061       // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10062       d = Bits32(opcode, 15, 12);
10063       m = Bits32(opcode, 3, 0);
10064       setflags = BitIsSet(opcode, 20);
10065 
10066       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10067       // instructions;
10068       if (d == 15 && setflags)
10069         EmulateSUBSPcLrEtc(opcode, encoding);
10070 
10071       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10072       shift_n = DecodeImmShiftARM(opcode, shift_t);
10073       break;
10074 
10075     default:
10076       return false;
10077     }
10078 
10079     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10080     uint32_t Rm = ReadCoreReg(m, &success);
10081     if (!success)
10082       return false;
10083 
10084     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10085     if (!success)
10086       return false;
10087 
10088     // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10089     uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10090     if (!success)
10091       return false;
10092 
10093     AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10094 
10095     EmulateInstruction::Context context;
10096     context.type = eContextArithmetic;
10097     RegisterInfo sp_reg;
10098     GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10099     RegisterInfo dwarf_reg;
10100     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10101     context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10102 
10103     if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10104                                    res.carry_out, res.overflow))
10105       return false;
10106   }
10107   return true;
10108 }
10109 
10110 // A8.6.7 ADD (register-shifted register)
EmulateADDRegShift(const uint32_t opcode,const ARMEncoding encoding)10111 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10112                                                const ARMEncoding encoding) {
10113 #if 0
10114     if ConditionPassed() then
10115         EncodingSpecificOperations();
10116         shift_n = UInt(R[s]<7:0>);
10117         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10118         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10119         R[d] = result;
10120         if setflags then
10121             APSR.N = result<31>;
10122             APSR.Z = IsZeroBit(result);
10123             APSR.C = carry;
10124             APSR.V = overflow;
10125 #endif
10126 
10127   bool success = false;
10128 
10129   if (ConditionPassed(opcode)) {
10130     uint32_t d;
10131     uint32_t n;
10132     uint32_t m;
10133     uint32_t s;
10134     bool setflags;
10135     ARM_ShifterType shift_t;
10136 
10137     switch (encoding) {
10138     case eEncodingA1:
10139       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10140       d = Bits32(opcode, 15, 12);
10141       n = Bits32(opcode, 19, 16);
10142       m = Bits32(opcode, 3, 0);
10143       s = Bits32(opcode, 11, 8);
10144 
10145       // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10146       setflags = BitIsSet(opcode, 20);
10147       shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10148 
10149       // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10150       if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10151         return false;
10152       break;
10153 
10154     default:
10155       return false;
10156     }
10157 
10158     // shift_n = UInt(R[s]<7:0>);
10159     uint32_t Rs = ReadCoreReg(s, &success);
10160     if (!success)
10161       return false;
10162 
10163     uint32_t shift_n = Bits32(Rs, 7, 0);
10164 
10165     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10166     uint32_t Rm = ReadCoreReg(m, &success);
10167     if (!success)
10168       return false;
10169 
10170     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10171     if (!success)
10172       return false;
10173 
10174     // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10175     uint32_t Rn = ReadCoreReg(n, &success);
10176     if (!success)
10177       return false;
10178 
10179     AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10180 
10181     // R[d] = result;
10182     EmulateInstruction::Context context;
10183     context.type = eContextArithmetic;
10184     RegisterInfo reg_n;
10185     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10186     RegisterInfo reg_m;
10187     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10188 
10189     context.SetRegisterRegisterOperands(reg_n, reg_m);
10190 
10191     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10192                                res.result))
10193       return false;
10194 
10195     // if setflags then
10196     // APSR.N = result<31>;
10197     // APSR.Z = IsZeroBit(result);
10198     // APSR.C = carry;
10199     // APSR.V = overflow;
10200     if (setflags)
10201       return WriteFlags(context, res.result, res.carry_out, res.overflow);
10202   }
10203   return true;
10204 }
10205 
10206 // A8.6.213 SUB (register)
EmulateSUBReg(const uint32_t opcode,const ARMEncoding encoding)10207 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10208                                           const ARMEncoding encoding) {
10209 #if 0
10210     if ConditionPassed() then
10211         EncodingSpecificOperations();
10212         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10213         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10214         if d == 15 then // Can only occur for ARM encoding
10215             ALUWritePC(result); // setflags is always FALSE here
10216         else
10217             R[d] = result;
10218             if setflags then
10219                 APSR.N = result<31>;
10220                 APSR.Z = IsZeroBit(result);
10221                 APSR.C = carry;
10222                 APSR.V = overflow;
10223 #endif
10224 
10225   bool success = false;
10226 
10227   if (ConditionPassed(opcode)) {
10228     uint32_t d;
10229     uint32_t n;
10230     uint32_t m;
10231     bool setflags;
10232     ARM_ShifterType shift_t;
10233     uint32_t shift_n;
10234 
10235     switch (encoding) {
10236     case eEncodingT1:
10237       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10238       d = Bits32(opcode, 2, 0);
10239       n = Bits32(opcode, 5, 3);
10240       m = Bits32(opcode, 8, 6);
10241       setflags = !InITBlock();
10242 
10243       // (shift_t, shift_n) = (SRType_LSL, 0);
10244       shift_t = SRType_LSL;
10245       shift_n = 0;
10246 
10247       break;
10248 
10249     case eEncodingT2:
10250       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10251       d = Bits32(opcode, 11, 8);
10252       n = Bits32(opcode, 19, 16);
10253       m = Bits32(opcode, 3, 0);
10254       setflags = BitIsSet(opcode, 20);
10255 
10256       // if Rd == "1111" && S == "1" then SEE CMP (register);
10257       if (d == 15 && setflags == 1)
10258         return EmulateCMPImm(opcode, eEncodingT3);
10259 
10260       // if Rn == "1101" then SEE SUB (SP minus register);
10261       if (n == 13)
10262         return EmulateSUBSPReg(opcode, eEncodingT1);
10263 
10264       // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10265       shift_n = DecodeImmShiftThumb(opcode, shift_t);
10266 
10267       // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10268       // UNPREDICTABLE;
10269       if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10270           BadReg(m))
10271         return false;
10272 
10273       break;
10274 
10275     case eEncodingA1:
10276       // if Rn == '1101' then SEE SUB (SP minus register);
10277       // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10278       d = Bits32(opcode, 15, 12);
10279       n = Bits32(opcode, 19, 16);
10280       m = Bits32(opcode, 3, 0);
10281       setflags = BitIsSet(opcode, 20);
10282 
10283       // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10284       // instructions;
10285       if ((d == 15) && setflags)
10286         EmulateSUBSPcLrEtc(opcode, encoding);
10287 
10288       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10289       shift_n = DecodeImmShiftARM(opcode, shift_t);
10290 
10291       break;
10292 
10293     default:
10294       return false;
10295     }
10296 
10297     // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10298     uint32_t Rm = ReadCoreReg(m, &success);
10299     if (!success)
10300       return false;
10301 
10302     uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10303     if (!success)
10304       return false;
10305 
10306     // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10307     uint32_t Rn = ReadCoreReg(n, &success);
10308     if (!success)
10309       return false;
10310 
10311     AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10312 
10313     // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10314     // // setflags is always FALSE here else
10315     // R[d] = result;
10316     // if setflags then
10317     // APSR.N = result<31>;
10318     // APSR.Z = IsZeroBit(result);
10319     // APSR.C = carry;
10320     // APSR.V = overflow;
10321 
10322     EmulateInstruction::Context context;
10323     context.type = eContextArithmetic;
10324     RegisterInfo reg_n;
10325     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10326     RegisterInfo reg_m;
10327     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10328     context.SetRegisterRegisterOperands(reg_n, reg_m);
10329 
10330     if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10331                                    res.carry_out, res.overflow))
10332       return false;
10333   }
10334   return true;
10335 }
10336 
10337 // A8.6.202 STREX
10338 // Store Register Exclusive calculates an address from a base register value
10339 // and an immediate offset, and stores a word from a register to memory if the
10340 // executing processor has exclusive access to the memory addressed.
EmulateSTREX(const uint32_t opcode,const ARMEncoding encoding)10341 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10342                                          const ARMEncoding encoding) {
10343 #if 0
10344     if ConditionPassed() then
10345         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10346         address = R[n] + imm32;
10347         if ExclusiveMonitorsPass(address,4) then
10348             MemA[address,4] = R[t];
10349             R[d] = 0;
10350         else
10351             R[d] = 1;
10352 #endif
10353 
10354   bool success = false;
10355 
10356   if (ConditionPassed(opcode)) {
10357     uint32_t d;
10358     uint32_t t;
10359     uint32_t n;
10360     uint32_t imm32;
10361     const uint32_t addr_byte_size = GetAddressByteSize();
10362 
10363     switch (encoding) {
10364     case eEncodingT1:
10365       // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10366       // ZeroExtend(imm8:'00',
10367       // 32);
10368       d = Bits32(opcode, 11, 8);
10369       t = Bits32(opcode, 15, 12);
10370       n = Bits32(opcode, 19, 16);
10371       imm32 = Bits32(opcode, 7, 0) << 2;
10372 
10373       // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10374       if (BadReg(d) || BadReg(t) || (n == 15))
10375         return false;
10376 
10377       // if d == n || d == t then UNPREDICTABLE;
10378       if ((d == n) || (d == t))
10379         return false;
10380 
10381       break;
10382 
10383     case eEncodingA1:
10384       // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10385       // offset
10386       d = Bits32(opcode, 15, 12);
10387       t = Bits32(opcode, 3, 0);
10388       n = Bits32(opcode, 19, 16);
10389       imm32 = 0;
10390 
10391       // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10392       if ((d == 15) || (t == 15) || (n == 15))
10393         return false;
10394 
10395       // if d == n || d == t then UNPREDICTABLE;
10396       if ((d == n) || (d == t))
10397         return false;
10398 
10399       break;
10400 
10401     default:
10402       return false;
10403     }
10404 
10405     // address = R[n] + imm32;
10406     uint32_t Rn = ReadCoreReg(n, &success);
10407     if (!success)
10408       return false;
10409 
10410     addr_t address = Rn + imm32;
10411 
10412     RegisterInfo base_reg;
10413     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10414     RegisterInfo data_reg;
10415     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10416     EmulateInstruction::Context context;
10417     context.type = eContextRegisterStore;
10418     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10419 
10420     // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10421     // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10422     // will say this
10423     //                                                         always return
10424     //                                                         true.
10425     if (true) {
10426       // MemA[address,4] = R[t];
10427       uint32_t Rt =
10428           ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10429       if (!success)
10430         return false;
10431 
10432       if (!MemAWrite(context, address, Rt, addr_byte_size))
10433         return false;
10434 
10435       // R[d] = 0;
10436       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10437         return false;
10438     }
10439 #if 0  // unreachable because if true
10440         else
10441         {
10442             // R[d] = 1;
10443             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10444                 return false;
10445         }
10446 #endif // unreachable because if true
10447   }
10448   return true;
10449 }
10450 
10451 // A8.6.197 STRB (immediate, ARM)
EmulateSTRBImmARM(const uint32_t opcode,const ARMEncoding encoding)10452 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10453                                               const ARMEncoding encoding) {
10454 #if 0
10455     if ConditionPassed() then
10456         EncodingSpecificOperations();
10457         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10458         address = if index then offset_addr else R[n];
10459         MemU[address,1] = R[t]<7:0>;
10460         if wback then R[n] = offset_addr;
10461 #endif
10462 
10463   bool success = false;
10464 
10465   if (ConditionPassed(opcode)) {
10466     uint32_t t;
10467     uint32_t n;
10468     uint32_t imm32;
10469     bool index;
10470     bool add;
10471     bool wback;
10472 
10473     switch (encoding) {
10474     case eEncodingA1:
10475       // if P == '0' && W == '1' then SEE STRBT;
10476       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10477       t = Bits32(opcode, 15, 12);
10478       n = Bits32(opcode, 19, 16);
10479       imm32 = Bits32(opcode, 11, 0);
10480 
10481       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10482       index = BitIsSet(opcode, 24);
10483       add = BitIsSet(opcode, 23);
10484       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10485 
10486       // if t == 15 then UNPREDICTABLE;
10487       if (t == 15)
10488         return false;
10489 
10490       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10491       if (wback && ((n == 15) || (n == t)))
10492         return false;
10493 
10494       break;
10495 
10496     default:
10497       return false;
10498     }
10499 
10500     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10501     uint32_t Rn = ReadCoreReg(n, &success);
10502     if (!success)
10503       return false;
10504 
10505     addr_t offset_addr;
10506     if (add)
10507       offset_addr = Rn + imm32;
10508     else
10509       offset_addr = Rn - imm32;
10510 
10511     // address = if index then offset_addr else R[n];
10512     addr_t address;
10513     if (index)
10514       address = offset_addr;
10515     else
10516       address = Rn;
10517 
10518     // MemU[address,1] = R[t]<7:0>;
10519     uint32_t Rt = ReadCoreReg(t, &success);
10520     if (!success)
10521       return false;
10522 
10523     RegisterInfo base_reg;
10524     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10525     RegisterInfo data_reg;
10526     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10527     EmulateInstruction::Context context;
10528     context.type = eContextRegisterStore;
10529     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10530 
10531     if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10532       return false;
10533 
10534     // if wback then R[n] = offset_addr;
10535     if (wback) {
10536       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10537                                  offset_addr))
10538         return false;
10539     }
10540   }
10541   return true;
10542 }
10543 
10544 // A8.6.194 STR (immediate, ARM)
EmulateSTRImmARM(const uint32_t opcode,const ARMEncoding encoding)10545 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10546                                              const ARMEncoding encoding) {
10547 #if 0
10548     if ConditionPassed() then
10549         EncodingSpecificOperations();
10550         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10551         address = if index then offset_addr else R[n];
10552         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10553         if wback then R[n] = offset_addr;
10554 #endif
10555 
10556   bool success = false;
10557 
10558   if (ConditionPassed(opcode)) {
10559     uint32_t t;
10560     uint32_t n;
10561     uint32_t imm32;
10562     bool index;
10563     bool add;
10564     bool wback;
10565 
10566     const uint32_t addr_byte_size = GetAddressByteSize();
10567 
10568     switch (encoding) {
10569     case eEncodingA1:
10570       // if P == '0' && W == '1' then SEE STRT;
10571       // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10572       // '000000000100' then SEE PUSH;
10573       // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10574       t = Bits32(opcode, 15, 12);
10575       n = Bits32(opcode, 19, 16);
10576       imm32 = Bits32(opcode, 11, 0);
10577 
10578       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10579       index = BitIsSet(opcode, 24);
10580       add = BitIsSet(opcode, 23);
10581       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10582 
10583       // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10584       if (wback && ((n == 15) || (n == t)))
10585         return false;
10586 
10587       break;
10588 
10589     default:
10590       return false;
10591     }
10592 
10593     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10594     uint32_t Rn = ReadCoreReg(n, &success);
10595     if (!success)
10596       return false;
10597 
10598     addr_t offset_addr;
10599     if (add)
10600       offset_addr = Rn + imm32;
10601     else
10602       offset_addr = Rn - imm32;
10603 
10604     // address = if index then offset_addr else R[n];
10605     addr_t address;
10606     if (index)
10607       address = offset_addr;
10608     else
10609       address = Rn;
10610 
10611     RegisterInfo base_reg;
10612     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10613     RegisterInfo data_reg;
10614     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10615     EmulateInstruction::Context context;
10616     context.type = eContextRegisterStore;
10617     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10618 
10619     // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10620     uint32_t Rt = ReadCoreReg(t, &success);
10621     if (!success)
10622       return false;
10623 
10624     if (t == 15) {
10625       uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10626       if (!success)
10627         return false;
10628 
10629       if (!MemUWrite(context, address, pc_value, addr_byte_size))
10630         return false;
10631     } else {
10632       if (!MemUWrite(context, address, Rt, addr_byte_size))
10633         return false;
10634     }
10635 
10636     // if wback then R[n] = offset_addr;
10637     if (wback) {
10638       context.type = eContextAdjustBaseRegister;
10639       context.SetImmediate(offset_addr);
10640 
10641       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10642                                  offset_addr))
10643         return false;
10644     }
10645   }
10646   return true;
10647 }
10648 
10649 // A8.6.66 LDRD (immediate)
10650 // Load Register Dual (immediate) calculates an address from a base register
10651 // value and an immediate offset, loads two words from memory, and writes them
10652 // to two registers.  It can use offset, post-indexed, or pre-indexed
10653 // addressing.
EmulateLDRDImmediate(const uint32_t opcode,const ARMEncoding encoding)10654 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10655                                                  const ARMEncoding encoding) {
10656 #if 0
10657     if ConditionPassed() then
10658         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10659         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10660         address = if index then offset_addr else R[n];
10661         R[t] = MemA[address,4];
10662         R[t2] = MemA[address+4,4];
10663         if wback then R[n] = offset_addr;
10664 #endif
10665 
10666   bool success = false;
10667 
10668   if (ConditionPassed(opcode)) {
10669     uint32_t t;
10670     uint32_t t2;
10671     uint32_t n;
10672     uint32_t imm32;
10673     bool index;
10674     bool add;
10675     bool wback;
10676 
10677     switch (encoding) {
10678     case eEncodingT1:
10679       // if P == '0' && W == '0' then SEE 'Related encodings';
10680       // if Rn == '1111' then SEE LDRD (literal);
10681       // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10682       // ZeroExtend(imm8:'00', 32);
10683       t = Bits32(opcode, 15, 12);
10684       t2 = Bits32(opcode, 11, 8);
10685       n = Bits32(opcode, 19, 16);
10686       imm32 = Bits32(opcode, 7, 0) << 2;
10687 
10688       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10689       index = BitIsSet(opcode, 24);
10690       add = BitIsSet(opcode, 23);
10691       wback = BitIsSet(opcode, 21);
10692 
10693       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10694       if (wback && ((n == t) || (n == t2)))
10695         return false;
10696 
10697       // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10698       if (BadReg(t) || BadReg(t2) || (t == t2))
10699         return false;
10700 
10701       break;
10702 
10703     case eEncodingA1:
10704       // if Rn == '1111' then SEE LDRD (literal);
10705       // if Rt<0> == '1' then UNPREDICTABLE;
10706       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10707       // 32);
10708       t = Bits32(opcode, 15, 12);
10709       if (BitIsSet(t, 0))
10710         return false;
10711       t2 = t + 1;
10712       n = Bits32(opcode, 19, 16);
10713       imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10714 
10715       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10716       index = BitIsSet(opcode, 24);
10717       add = BitIsSet(opcode, 23);
10718       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10719 
10720       // if P == '0' && W == '1' then UNPREDICTABLE;
10721       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10722         return false;
10723 
10724       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10725       if (wback && ((n == t) || (n == t2)))
10726         return false;
10727 
10728       // if t2 == 15 then UNPREDICTABLE;
10729       if (t2 == 15)
10730         return false;
10731 
10732       break;
10733 
10734     default:
10735       return false;
10736     }
10737 
10738     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10739     uint32_t Rn = ReadCoreReg(n, &success);
10740     if (!success)
10741       return false;
10742 
10743     addr_t offset_addr;
10744     if (add)
10745       offset_addr = Rn + imm32;
10746     else
10747       offset_addr = Rn - imm32;
10748 
10749     // address = if index then offset_addr else R[n];
10750     addr_t address;
10751     if (index)
10752       address = offset_addr;
10753     else
10754       address = Rn;
10755 
10756     // R[t] = MemA[address,4];
10757     RegisterInfo base_reg;
10758     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10759 
10760     EmulateInstruction::Context context;
10761     if (n == 13)
10762       context.type = eContextPopRegisterOffStack;
10763     else
10764       context.type = eContextRegisterLoad;
10765     context.SetAddress(address);
10766 
10767     const uint32_t addr_byte_size = GetAddressByteSize();
10768     uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10769     if (!success)
10770       return false;
10771 
10772     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10773       return false;
10774 
10775     // R[t2] = MemA[address+4,4];
10776     context.SetAddress(address + 4);
10777     data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10778     if (!success)
10779       return false;
10780 
10781     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10782                                data))
10783       return false;
10784 
10785     // if wback then R[n] = offset_addr;
10786     if (wback) {
10787       context.type = eContextAdjustBaseRegister;
10788       context.SetAddress(offset_addr);
10789 
10790       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10791                                  offset_addr))
10792         return false;
10793     }
10794   }
10795   return true;
10796 }
10797 
10798 // A8.6.68 LDRD (register)
10799 // Load Register Dual (register) calculates an address from a base register
10800 // value and a register offset, loads two words from memory, and writes them to
10801 // two registers.  It can use offset, post-indexed or pre-indexed addressing.
EmulateLDRDRegister(const uint32_t opcode,const ARMEncoding encoding)10802 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10803                                                 const ARMEncoding encoding) {
10804 #if 0
10805     if ConditionPassed() then
10806         EncodingSpecificOperations();
10807         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10808         address = if index then offset_addr else R[n];
10809         R[t] = MemA[address,4];
10810         R[t2] = MemA[address+4,4];
10811         if wback then R[n] = offset_addr;
10812 #endif
10813 
10814   bool success = false;
10815 
10816   if (ConditionPassed(opcode)) {
10817     uint32_t t;
10818     uint32_t t2;
10819     uint32_t n;
10820     uint32_t m;
10821     bool index;
10822     bool add;
10823     bool wback;
10824 
10825     switch (encoding) {
10826     case eEncodingA1:
10827       // if Rt<0> == '1' then UNPREDICTABLE;
10828       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10829       t = Bits32(opcode, 15, 12);
10830       if (BitIsSet(t, 0))
10831         return false;
10832       t2 = t + 1;
10833       n = Bits32(opcode, 19, 16);
10834       m = Bits32(opcode, 3, 0);
10835 
10836       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10837       index = BitIsSet(opcode, 24);
10838       add = BitIsSet(opcode, 23);
10839       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10840 
10841       // if P == '0' && W == '1' then UNPREDICTABLE;
10842       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10843         return false;
10844 
10845       // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10846       if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10847         return false;
10848 
10849       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10850       if (wback && ((n == 15) || (n == t) || (n == t2)))
10851         return false;
10852 
10853       // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10854       if ((ArchVersion() < 6) && wback && (m == n))
10855         return false;
10856       break;
10857 
10858     default:
10859       return false;
10860     }
10861 
10862     uint32_t Rn = ReadCoreReg(n, &success);
10863     if (!success)
10864       return false;
10865     RegisterInfo base_reg;
10866     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10867 
10868     uint32_t Rm = ReadCoreReg(m, &success);
10869     if (!success)
10870       return false;
10871     RegisterInfo offset_reg;
10872     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10873 
10874     // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10875     addr_t offset_addr;
10876     if (add)
10877       offset_addr = Rn + Rm;
10878     else
10879       offset_addr = Rn - Rm;
10880 
10881     // address = if index then offset_addr else R[n];
10882     addr_t address;
10883     if (index)
10884       address = offset_addr;
10885     else
10886       address = Rn;
10887 
10888     EmulateInstruction::Context context;
10889     if (n == 13)
10890       context.type = eContextPopRegisterOffStack;
10891     else
10892       context.type = eContextRegisterLoad;
10893     context.SetAddress(address);
10894 
10895     // R[t] = MemA[address,4];
10896     const uint32_t addr_byte_size = GetAddressByteSize();
10897     uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10898     if (!success)
10899       return false;
10900 
10901     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10902       return false;
10903 
10904     // R[t2] = MemA[address+4,4];
10905 
10906     data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10907     if (!success)
10908       return false;
10909 
10910     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10911                                data))
10912       return false;
10913 
10914     // if wback then R[n] = offset_addr;
10915     if (wback) {
10916       context.type = eContextAdjustBaseRegister;
10917       context.SetAddress(offset_addr);
10918 
10919       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10920                                  offset_addr))
10921         return false;
10922     }
10923   }
10924   return true;
10925 }
10926 
10927 // A8.6.200 STRD (immediate)
10928 // Store Register Dual (immediate) calculates an address from a base register
10929 // value and an immediate offset, and stores two words from two registers to
10930 // memory.  It can use offset, post-indexed, or pre-indexed addressing.
EmulateSTRDImm(const uint32_t opcode,const ARMEncoding encoding)10931 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10932                                            const ARMEncoding encoding) {
10933 #if 0
10934     if ConditionPassed() then
10935         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10936         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10937         address = if index then offset_addr else R[n];
10938         MemA[address,4] = R[t];
10939         MemA[address+4,4] = R[t2];
10940         if wback then R[n] = offset_addr;
10941 #endif
10942 
10943   bool success = false;
10944 
10945   if (ConditionPassed(opcode)) {
10946     uint32_t t;
10947     uint32_t t2;
10948     uint32_t n;
10949     uint32_t imm32;
10950     bool index;
10951     bool add;
10952     bool wback;
10953 
10954     switch (encoding) {
10955     case eEncodingT1:
10956       // if P == '0' && W == '0' then SEE 'Related encodings';
10957       // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10958       // ZeroExtend(imm8:'00', 32);
10959       t = Bits32(opcode, 15, 12);
10960       t2 = Bits32(opcode, 11, 8);
10961       n = Bits32(opcode, 19, 16);
10962       imm32 = Bits32(opcode, 7, 0) << 2;
10963 
10964       // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10965       index = BitIsSet(opcode, 24);
10966       add = BitIsSet(opcode, 23);
10967       wback = BitIsSet(opcode, 21);
10968 
10969       // if wback && (n == t || n == t2) then UNPREDICTABLE;
10970       if (wback && ((n == t) || (n == t2)))
10971         return false;
10972 
10973       // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10974       if ((n == 15) || BadReg(t) || BadReg(t2))
10975         return false;
10976 
10977       break;
10978 
10979     case eEncodingA1:
10980       // if Rt<0> == '1' then UNPREDICTABLE;
10981       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10982       // 32);
10983       t = Bits32(opcode, 15, 12);
10984       if (BitIsSet(t, 0))
10985         return false;
10986 
10987       t2 = t + 1;
10988       n = Bits32(opcode, 19, 16);
10989       imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10990 
10991       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10992       index = BitIsSet(opcode, 24);
10993       add = BitIsSet(opcode, 23);
10994       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10995 
10996       // if P == '0' && W == '1' then UNPREDICTABLE;
10997       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10998         return false;
10999 
11000       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11001       if (wback && ((n == 15) || (n == t) || (n == t2)))
11002         return false;
11003 
11004       // if t2 == 15 then UNPREDICTABLE;
11005       if (t2 == 15)
11006         return false;
11007 
11008       break;
11009 
11010     default:
11011       return false;
11012     }
11013 
11014     RegisterInfo base_reg;
11015     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11016 
11017     uint32_t Rn = ReadCoreReg(n, &success);
11018     if (!success)
11019       return false;
11020 
11021     // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11022     addr_t offset_addr;
11023     if (add)
11024       offset_addr = Rn + imm32;
11025     else
11026       offset_addr = Rn - imm32;
11027 
11028     // address = if index then offset_addr else R[n];
11029     addr_t address;
11030     if (index)
11031       address = offset_addr;
11032     else
11033       address = Rn;
11034 
11035     // MemA[address,4] = R[t];
11036     RegisterInfo data_reg;
11037     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11038 
11039     uint32_t data = ReadCoreReg(t, &success);
11040     if (!success)
11041       return false;
11042 
11043     EmulateInstruction::Context context;
11044     if (n == 13)
11045       context.type = eContextPushRegisterOnStack;
11046     else
11047       context.type = eContextRegisterStore;
11048     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11049 
11050     const uint32_t addr_byte_size = GetAddressByteSize();
11051 
11052     if (!MemAWrite(context, address, data, addr_byte_size))
11053       return false;
11054 
11055     // MemA[address+4,4] = R[t2];
11056     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11057     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11058                                             (address + 4) - Rn);
11059 
11060     data = ReadCoreReg(t2, &success);
11061     if (!success)
11062       return false;
11063 
11064     if (!MemAWrite(context, address + 4, data, addr_byte_size))
11065       return false;
11066 
11067     // if wback then R[n] = offset_addr;
11068     if (wback) {
11069       if (n == 13)
11070         context.type = eContextAdjustStackPointer;
11071       else
11072         context.type = eContextAdjustBaseRegister;
11073       context.SetAddress(offset_addr);
11074 
11075       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11076                                  offset_addr))
11077         return false;
11078     }
11079   }
11080   return true;
11081 }
11082 
11083 // A8.6.201 STRD (register)
EmulateSTRDReg(const uint32_t opcode,const ARMEncoding encoding)11084 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11085                                            const ARMEncoding encoding) {
11086 #if 0
11087     if ConditionPassed() then
11088         EncodingSpecificOperations();
11089         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11090         address = if index then offset_addr else R[n];
11091         MemA[address,4] = R[t];
11092         MemA[address+4,4] = R[t2];
11093         if wback then R[n] = offset_addr;
11094 #endif
11095 
11096   bool success = false;
11097 
11098   if (ConditionPassed(opcode)) {
11099     uint32_t t;
11100     uint32_t t2;
11101     uint32_t n;
11102     uint32_t m;
11103     bool index;
11104     bool add;
11105     bool wback;
11106 
11107     switch (encoding) {
11108     case eEncodingA1:
11109       // if Rt<0> == '1' then UNPREDICTABLE;
11110       // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11111       t = Bits32(opcode, 15, 12);
11112       if (BitIsSet(t, 0))
11113         return false;
11114 
11115       t2 = t + 1;
11116       n = Bits32(opcode, 19, 16);
11117       m = Bits32(opcode, 3, 0);
11118 
11119       // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11120       index = BitIsSet(opcode, 24);
11121       add = BitIsSet(opcode, 23);
11122       wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11123 
11124       // if P == '0' && W == '1' then UNPREDICTABLE;
11125       if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11126         return false;
11127 
11128       // if t2 == 15 || m == 15 then UNPREDICTABLE;
11129       if ((t2 == 15) || (m == 15))
11130         return false;
11131 
11132       // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11133       if (wback && ((n == 15) || (n == t) || (n == t2)))
11134         return false;
11135 
11136       // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11137       if ((ArchVersion() < 6) && wback && (m == n))
11138         return false;
11139 
11140       break;
11141 
11142     default:
11143       return false;
11144     }
11145 
11146     RegisterInfo base_reg;
11147     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11148     RegisterInfo offset_reg;
11149     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11150     RegisterInfo data_reg;
11151 
11152     uint32_t Rn = ReadCoreReg(n, &success);
11153     if (!success)
11154       return false;
11155 
11156     uint32_t Rm = ReadCoreReg(m, &success);
11157     if (!success)
11158       return false;
11159 
11160     // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11161     addr_t offset_addr;
11162     if (add)
11163       offset_addr = Rn + Rm;
11164     else
11165       offset_addr = Rn - Rm;
11166 
11167     // address = if index then offset_addr else R[n];
11168     addr_t address;
11169     if (index)
11170       address = offset_addr;
11171     else
11172       address = Rn;
11173     // MemA[address,4] = R[t];
11174     uint32_t Rt = ReadCoreReg(t, &success);
11175     if (!success)
11176       return false;
11177 
11178     EmulateInstruction::Context context;
11179     if (t == 13)
11180       context.type = eContextPushRegisterOnStack;
11181     else
11182       context.type = eContextRegisterStore;
11183 
11184     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11185     context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11186                                                     data_reg);
11187 
11188     const uint32_t addr_byte_size = GetAddressByteSize();
11189 
11190     if (!MemAWrite(context, address, Rt, addr_byte_size))
11191       return false;
11192 
11193     // MemA[address+4,4] = R[t2];
11194     uint32_t Rt2 = ReadCoreReg(t2, &success);
11195     if (!success)
11196       return false;
11197 
11198     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11199 
11200     context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11201                                                     data_reg);
11202 
11203     if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11204       return false;
11205 
11206     // if wback then R[n] = offset_addr;
11207     if (wback) {
11208       context.type = eContextAdjustBaseRegister;
11209       context.SetAddress(offset_addr);
11210 
11211       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11212                                  offset_addr))
11213         return false;
11214     }
11215   }
11216   return true;
11217 }
11218 
11219 // A8.6.319 VLDM
11220 // Vector Load Multiple loads multiple extension registers from consecutive
11221 // memory locations using an address from an ARM core register.
EmulateVLDM(const uint32_t opcode,const ARMEncoding encoding)11222 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11223                                         const ARMEncoding encoding) {
11224 #if 0
11225     if ConditionPassed() then
11226         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11227         address = if add then R[n] else R[n]-imm32;
11228         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11229         for r = 0 to regs-1
11230             if single_regs then
11231                 S[d+r] = MemA[address,4]; address = address+4;
11232             else
11233                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11234                 // Combine the word-aligned words in the correct order for
11235                 // current endianness.
11236                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11237 #endif
11238 
11239   bool success = false;
11240 
11241   if (ConditionPassed(opcode)) {
11242     bool single_regs;
11243     bool add;
11244     bool wback;
11245     uint32_t d;
11246     uint32_t n;
11247     uint32_t imm32;
11248     uint32_t regs;
11249 
11250     switch (encoding) {
11251     case eEncodingT1:
11252     case eEncodingA1:
11253       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11254       // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11255       // if P == '1' && W == '0' then SEE VLDR;
11256       // if P == U && W == '1' then UNDEFINED;
11257       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11258         return false;
11259 
11260       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11261       // !), 101 (DB with !)
11262       // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11263       single_regs = false;
11264       add = BitIsSet(opcode, 23);
11265       wback = BitIsSet(opcode, 21);
11266 
11267       // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11268       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11269       n = Bits32(opcode, 19, 16);
11270       imm32 = Bits32(opcode, 7, 0) << 2;
11271 
11272       // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11273       regs = Bits32(opcode, 7, 0) / 2;
11274 
11275       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11276       // UNPREDICTABLE;
11277       if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11278         return false;
11279 
11280       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11281       if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11282         return false;
11283 
11284       break;
11285 
11286     case eEncodingT2:
11287     case eEncodingA2:
11288       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11289       // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11290       // if P == '1' && W == '0' then SEE VLDR;
11291       // if P == U && W == '1' then UNDEFINED;
11292       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11293         return false;
11294 
11295       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11296       // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11297       // == '1'); d =
11298       // UInt(Vd:D); n = UInt(Rn);
11299       single_regs = true;
11300       add = BitIsSet(opcode, 23);
11301       wback = BitIsSet(opcode, 21);
11302       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11303       n = Bits32(opcode, 19, 16);
11304 
11305       // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11306       imm32 = Bits32(opcode, 7, 0) << 2;
11307       regs = Bits32(opcode, 7, 0);
11308 
11309       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11310       // UNPREDICTABLE;
11311       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11312         return false;
11313 
11314       // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11315       if ((regs == 0) || ((d + regs) > 32))
11316         return false;
11317       break;
11318 
11319     default:
11320       return false;
11321     }
11322 
11323     RegisterInfo base_reg;
11324     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11325 
11326     uint32_t Rn = ReadCoreReg(n, &success);
11327     if (!success)
11328       return false;
11329 
11330     // address = if add then R[n] else R[n]-imm32;
11331     addr_t address;
11332     if (add)
11333       address = Rn;
11334     else
11335       address = Rn - imm32;
11336 
11337     // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11338     EmulateInstruction::Context context;
11339 
11340     if (wback) {
11341       uint32_t value;
11342       if (add)
11343         value = Rn + imm32;
11344       else
11345         value = Rn - imm32;
11346 
11347       context.type = eContextAdjustBaseRegister;
11348       context.SetImmediateSigned(value - Rn);
11349       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11350                                  value))
11351         return false;
11352     }
11353 
11354     const uint32_t addr_byte_size = GetAddressByteSize();
11355     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11356 
11357     context.type = eContextRegisterLoad;
11358 
11359     // for r = 0 to regs-1
11360     for (uint32_t r = 0; r < regs; ++r) {
11361       if (single_regs) {
11362         // S[d+r] = MemA[address,4]; address = address+4;
11363         context.SetRegisterPlusOffset(base_reg, address - Rn);
11364 
11365         uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11366         if (!success)
11367           return false;
11368 
11369         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11370                                    start_reg + d + r, data))
11371           return false;
11372 
11373         address = address + 4;
11374       } else {
11375         // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11376         // address+8;
11377         context.SetRegisterPlusOffset(base_reg, address - Rn);
11378         uint32_t word1 =
11379             MemARead(context, address, addr_byte_size, 0, &success);
11380         if (!success)
11381           return false;
11382 
11383         context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11384         uint32_t word2 =
11385             MemARead(context, address + 4, addr_byte_size, 0, &success);
11386         if (!success)
11387           return false;
11388 
11389         address = address + 8;
11390         // // Combine the word-aligned words in the correct order for current
11391         // endianness.
11392         // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11393         uint64_t data;
11394         if (GetByteOrder() == eByteOrderBig) {
11395           data = word1;
11396           data = (data << 32) | word2;
11397         } else {
11398           data = word2;
11399           data = (data << 32) | word1;
11400         }
11401 
11402         if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11403                                    start_reg + d + r, data))
11404           return false;
11405       }
11406     }
11407   }
11408   return true;
11409 }
11410 
11411 // A8.6.399 VSTM
11412 // Vector Store Multiple stores multiple extension registers to consecutive
11413 // memory locations using an address from an
11414 // ARM core register.
EmulateVSTM(const uint32_t opcode,const ARMEncoding encoding)11415 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11416                                         const ARMEncoding encoding) {
11417 #if 0
11418     if ConditionPassed() then
11419         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11420         address = if add then R[n] else R[n]-imm32;
11421         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11422         for r = 0 to regs-1
11423             if single_regs then
11424                 MemA[address,4] = S[d+r]; address = address+4;
11425             else
11426                 // Store as two word-aligned words in the correct order for
11427                 // current endianness.
11428                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11429                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11430                 address = address+8;
11431 #endif
11432 
11433   bool success = false;
11434 
11435   if (ConditionPassed(opcode)) {
11436     bool single_regs;
11437     bool add;
11438     bool wback;
11439     uint32_t d;
11440     uint32_t n;
11441     uint32_t imm32;
11442     uint32_t regs;
11443 
11444     switch (encoding) {
11445     case eEncodingT1:
11446     case eEncodingA1:
11447       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11448       // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11449       // if P == '1' && W == '0' then SEE VSTR;
11450       // if P == U && W == '1' then UNDEFINED;
11451       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11452         return false;
11453 
11454       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11455       // !), 101 (DB with !)
11456       // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11457       single_regs = false;
11458       add = BitIsSet(opcode, 23);
11459       wback = BitIsSet(opcode, 21);
11460 
11461       // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11462       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11463       n = Bits32(opcode, 19, 16);
11464       imm32 = Bits32(opcode, 7, 0) << 2;
11465 
11466       // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11467       regs = Bits32(opcode, 7, 0) / 2;
11468 
11469       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11470       // UNPREDICTABLE;
11471       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11472         return false;
11473 
11474       // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11475       if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11476         return false;
11477 
11478       break;
11479 
11480     case eEncodingT2:
11481     case eEncodingA2:
11482       // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11483       // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11484       // if P == '1' && W == '0' then SEE VSTR;
11485       // if P == U && W == '1' then UNDEFINED;
11486       if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11487         return false;
11488 
11489       // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11490       // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11491       // == '1'); d =
11492       // UInt(Vd:D); n = UInt(Rn);
11493       single_regs = true;
11494       add = BitIsSet(opcode, 23);
11495       wback = BitIsSet(opcode, 21);
11496       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11497       n = Bits32(opcode, 19, 16);
11498 
11499       // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11500       imm32 = Bits32(opcode, 7, 0) << 2;
11501       regs = Bits32(opcode, 7, 0);
11502 
11503       // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11504       // UNPREDICTABLE;
11505       if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11506         return false;
11507 
11508       // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11509       if ((regs == 0) || ((d + regs) > 32))
11510         return false;
11511 
11512       break;
11513 
11514     default:
11515       return false;
11516     }
11517 
11518     RegisterInfo base_reg;
11519     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11520 
11521     uint32_t Rn = ReadCoreReg(n, &success);
11522     if (!success)
11523       return false;
11524 
11525     // address = if add then R[n] else R[n]-imm32;
11526     addr_t address;
11527     if (add)
11528       address = Rn;
11529     else
11530       address = Rn - imm32;
11531 
11532     EmulateInstruction::Context context;
11533     // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11534     if (wback) {
11535       uint32_t value;
11536       if (add)
11537         value = Rn + imm32;
11538       else
11539         value = Rn - imm32;
11540 
11541       context.type = eContextAdjustBaseRegister;
11542       context.SetRegisterPlusOffset(base_reg, value - Rn);
11543 
11544       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11545                                  value))
11546         return false;
11547     }
11548 
11549     const uint32_t addr_byte_size = GetAddressByteSize();
11550     uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11551 
11552     context.type = eContextRegisterStore;
11553     // for r = 0 to regs-1
11554     for (uint32_t r = 0; r < regs; ++r) {
11555 
11556       if (single_regs) {
11557         // MemA[address,4] = S[d+r]; address = address+4;
11558         uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11559                                              start_reg + d + r, 0, &success);
11560         if (!success)
11561           return false;
11562 
11563         RegisterInfo data_reg;
11564         GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11565         context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11566                                                 address - Rn);
11567         if (!MemAWrite(context, address, data, addr_byte_size))
11568           return false;
11569 
11570         address = address + 4;
11571       } else {
11572         // // Store as two word-aligned words in the correct order for current
11573         // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11574         // D[d+r]<31:0>;
11575         // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11576         // D[d+r]<63:32>;
11577         uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11578                                              start_reg + d + r, 0, &success);
11579         if (!success)
11580           return false;
11581 
11582         RegisterInfo data_reg;
11583         GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11584 
11585         if (GetByteOrder() == eByteOrderBig) {
11586           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11587                                                   address - Rn);
11588           if (!MemAWrite(context, address, Bits64(data, 63, 32),
11589                          addr_byte_size))
11590             return false;
11591 
11592           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11593                                                   (address + 4) - Rn);
11594           if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11595                          addr_byte_size))
11596             return false;
11597         } else {
11598           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11599                                                   address - Rn);
11600           if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11601             return false;
11602 
11603           context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11604                                                   (address + 4) - Rn);
11605           if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11606                          addr_byte_size))
11607             return false;
11608         }
11609         // address = address+8;
11610         address = address + 8;
11611       }
11612     }
11613   }
11614   return true;
11615 }
11616 
11617 // A8.6.320
11618 // This instruction loads a single extension register from memory, using an
11619 // address from an ARM core register, with an optional offset.
EmulateVLDR(const uint32_t opcode,ARMEncoding encoding)11620 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11621                                         ARMEncoding encoding) {
11622 #if 0
11623     if ConditionPassed() then
11624         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11625         base = if n == 15 then Align(PC,4) else R[n];
11626         address = if add then (base + imm32) else (base - imm32);
11627         if single_reg then
11628             S[d] = MemA[address,4];
11629         else
11630             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11631             // Combine the word-aligned words in the correct order for current
11632             // endianness.
11633             D[d] = if BigEndian() then word1:word2 else word2:word1;
11634 #endif
11635 
11636   bool success = false;
11637 
11638   if (ConditionPassed(opcode)) {
11639     bool single_reg;
11640     bool add;
11641     uint32_t imm32;
11642     uint32_t d;
11643     uint32_t n;
11644 
11645     switch (encoding) {
11646     case eEncodingT1:
11647     case eEncodingA1:
11648       // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11649       // 32);
11650       single_reg = false;
11651       add = BitIsSet(opcode, 23);
11652       imm32 = Bits32(opcode, 7, 0) << 2;
11653 
11654       // d = UInt(D:Vd); n = UInt(Rn);
11655       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11656       n = Bits32(opcode, 19, 16);
11657 
11658       break;
11659 
11660     case eEncodingT2:
11661     case eEncodingA2:
11662       // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11663       single_reg = true;
11664       add = BitIsSet(opcode, 23);
11665       imm32 = Bits32(opcode, 7, 0) << 2;
11666 
11667       // d = UInt(Vd:D); n = UInt(Rn);
11668       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11669       n = Bits32(opcode, 19, 16);
11670 
11671       break;
11672 
11673     default:
11674       return false;
11675     }
11676     RegisterInfo base_reg;
11677     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11678 
11679     uint32_t Rn = ReadCoreReg(n, &success);
11680     if (!success)
11681       return false;
11682 
11683     // base = if n == 15 then Align(PC,4) else R[n];
11684     uint32_t base;
11685     if (n == 15)
11686       base = AlignPC(Rn);
11687     else
11688       base = Rn;
11689 
11690     // address = if add then (base + imm32) else (base - imm32);
11691     addr_t address;
11692     if (add)
11693       address = base + imm32;
11694     else
11695       address = base - imm32;
11696 
11697     const uint32_t addr_byte_size = GetAddressByteSize();
11698     uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11699 
11700     EmulateInstruction::Context context;
11701     context.type = eContextRegisterLoad;
11702     context.SetRegisterPlusOffset(base_reg, address - base);
11703 
11704     if (single_reg) {
11705       // S[d] = MemA[address,4];
11706       uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11707       if (!success)
11708         return false;
11709 
11710       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11711                                  data))
11712         return false;
11713     } else {
11714       // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11715       uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11716       if (!success)
11717         return false;
11718 
11719       context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11720       uint32_t word2 =
11721           MemARead(context, address + 4, addr_byte_size, 0, &success);
11722       if (!success)
11723         return false;
11724       // // Combine the word-aligned words in the correct order for current
11725       // endianness.
11726       // D[d] = if BigEndian() then word1:word2 else word2:word1;
11727       uint64_t data64;
11728       if (GetByteOrder() == eByteOrderBig) {
11729         data64 = word1;
11730         data64 = (data64 << 32) | word2;
11731       } else {
11732         data64 = word2;
11733         data64 = (data64 << 32) | word1;
11734       }
11735 
11736       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11737                                  data64))
11738         return false;
11739     }
11740   }
11741   return true;
11742 }
11743 
11744 // A8.6.400 VSTR
11745 // This instruction stores a signle extension register to memory, using an
11746 // address from an ARM core register, with an optional offset.
EmulateVSTR(const uint32_t opcode,ARMEncoding encoding)11747 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11748                                         ARMEncoding encoding) {
11749 #if 0
11750     if ConditionPassed() then
11751         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11752         address = if add then (R[n] + imm32) else (R[n] - imm32);
11753         if single_reg then
11754             MemA[address,4] = S[d];
11755         else
11756             // Store as two word-aligned words in the correct order for current
11757             // endianness.
11758             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11759             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11760 #endif
11761 
11762   bool success = false;
11763 
11764   if (ConditionPassed(opcode)) {
11765     bool single_reg;
11766     bool add;
11767     uint32_t imm32;
11768     uint32_t d;
11769     uint32_t n;
11770 
11771     switch (encoding) {
11772     case eEncodingT1:
11773     case eEncodingA1:
11774       // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11775       // 32);
11776       single_reg = false;
11777       add = BitIsSet(opcode, 23);
11778       imm32 = Bits32(opcode, 7, 0) << 2;
11779 
11780       // d = UInt(D:Vd); n = UInt(Rn);
11781       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11782       n = Bits32(opcode, 19, 16);
11783 
11784       // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11785       if ((n == 15) && (CurrentInstrSet() != eModeARM))
11786         return false;
11787 
11788       break;
11789 
11790     case eEncodingT2:
11791     case eEncodingA2:
11792       // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11793       single_reg = true;
11794       add = BitIsSet(opcode, 23);
11795       imm32 = Bits32(opcode, 7, 0) << 2;
11796 
11797       // d = UInt(Vd:D); n = UInt(Rn);
11798       d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11799       n = Bits32(opcode, 19, 16);
11800 
11801       // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11802       if ((n == 15) && (CurrentInstrSet() != eModeARM))
11803         return false;
11804 
11805       break;
11806 
11807     default:
11808       return false;
11809     }
11810 
11811     RegisterInfo base_reg;
11812     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11813 
11814     uint32_t Rn = ReadCoreReg(n, &success);
11815     if (!success)
11816       return false;
11817 
11818     // address = if add then (R[n] + imm32) else (R[n] - imm32);
11819     addr_t address;
11820     if (add)
11821       address = Rn + imm32;
11822     else
11823       address = Rn - imm32;
11824 
11825     const uint32_t addr_byte_size = GetAddressByteSize();
11826     uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11827 
11828     RegisterInfo data_reg;
11829     GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11830     EmulateInstruction::Context context;
11831     context.type = eContextRegisterStore;
11832     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11833 
11834     if (single_reg) {
11835       // MemA[address,4] = S[d];
11836       uint32_t data =
11837           ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11838       if (!success)
11839         return false;
11840 
11841       if (!MemAWrite(context, address, data, addr_byte_size))
11842         return false;
11843     } else {
11844       // // Store as two word-aligned words in the correct order for current
11845       // endianness.
11846       // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11847       // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11848       uint64_t data =
11849           ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11850       if (!success)
11851         return false;
11852 
11853       if (GetByteOrder() == eByteOrderBig) {
11854         if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11855           return false;
11856 
11857         context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11858                                                 (address + 4) - Rn);
11859         if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11860                        addr_byte_size))
11861           return false;
11862       } else {
11863         if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11864           return false;
11865 
11866         context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11867                                                 (address + 4) - Rn);
11868         if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11869                        addr_byte_size))
11870           return false;
11871       }
11872     }
11873   }
11874   return true;
11875 }
11876 
11877 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11878 // from memory into one, two, three or four registers, without de-interleaving.
11879 // Every element of each register is loaded.
EmulateVLD1Multiple(const uint32_t opcode,ARMEncoding encoding)11880 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11881                                                 ARMEncoding encoding) {
11882 #if 0
11883     if ConditionPassed() then
11884         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11885         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11886         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11887         for r = 0 to regs-1
11888             for e = 0 to elements-1
11889                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11890                 address = address + ebytes;
11891 #endif
11892 
11893   bool success = false;
11894 
11895   if (ConditionPassed(opcode)) {
11896     uint32_t regs;
11897     uint32_t alignment;
11898     uint32_t ebytes;
11899     uint32_t esize;
11900     uint32_t elements;
11901     uint32_t d;
11902     uint32_t n;
11903     uint32_t m;
11904     bool wback;
11905     bool register_index;
11906 
11907     switch (encoding) {
11908     case eEncodingT1:
11909     case eEncodingA1: {
11910       // case type of
11911       // when '0111'
11912       // regs = 1; if align<1> == '1' then UNDEFINED;
11913       // when '1010'
11914       // regs = 2; if align == '11' then UNDEFINED;
11915       // when '0110'
11916       // regs = 3; if align<1> == '1' then UNDEFINED;
11917       // when '0010'
11918       // regs = 4;
11919       // otherwise
11920       // SEE 'Related encodings';
11921       uint32_t type = Bits32(opcode, 11, 8);
11922       uint32_t align = Bits32(opcode, 5, 4);
11923       if (type == 7) // '0111'
11924       {
11925         regs = 1;
11926         if (BitIsSet(align, 1))
11927           return false;
11928       } else if (type == 10) // '1010'
11929       {
11930         regs = 2;
11931         if (align == 3)
11932           return false;
11933 
11934       } else if (type == 6) // '0110'
11935       {
11936         regs = 3;
11937         if (BitIsSet(align, 1))
11938           return false;
11939       } else if (type == 2) // '0010'
11940       {
11941         regs = 4;
11942       } else
11943         return false;
11944 
11945       // alignment = if align == '00' then 1 else 4 << UInt(align);
11946       if (align == 0)
11947         alignment = 1;
11948       else
11949         alignment = 4 << align;
11950 
11951       // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11952       ebytes = 1 << Bits32(opcode, 7, 6);
11953       esize = 8 * ebytes;
11954       elements = 8 / ebytes;
11955 
11956       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11957       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11958       n = Bits32(opcode, 19, 15);
11959       m = Bits32(opcode, 3, 0);
11960 
11961       // wback = (m != 15); register_index = (m != 15 && m != 13);
11962       wback = (m != 15);
11963       register_index = ((m != 15) && (m != 13));
11964 
11965       // if d+regs > 32 then UNPREDICTABLE;
11966       if ((d + regs) > 32)
11967         return false;
11968     } break;
11969 
11970     default:
11971       return false;
11972     }
11973 
11974     RegisterInfo base_reg;
11975     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11976 
11977     uint32_t Rn = ReadCoreReg(n, &success);
11978     if (!success)
11979       return false;
11980 
11981     // address = R[n]; if (address MOD alignment) != 0 then
11982     // GenerateAlignmentException();
11983     addr_t address = Rn;
11984     if ((address % alignment) != 0)
11985       return false;
11986 
11987     EmulateInstruction::Context context;
11988     // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11989     if (wback) {
11990       uint32_t Rm = ReadCoreReg(m, &success);
11991       if (!success)
11992         return false;
11993 
11994       uint32_t offset;
11995       if (register_index)
11996         offset = Rm;
11997       else
11998         offset = 8 * regs;
11999 
12000       uint32_t value = Rn + offset;
12001       context.type = eContextAdjustBaseRegister;
12002       context.SetRegisterPlusOffset(base_reg, offset);
12003 
12004       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12005                                  value))
12006         return false;
12007     }
12008 
12009     // for r = 0 to regs-1
12010     for (uint32_t r = 0; r < regs; ++r) {
12011       // for e = 0 to elements-1
12012       uint64_t assembled_data = 0;
12013       for (uint32_t e = 0; e < elements; ++e) {
12014         // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12015         context.type = eContextRegisterLoad;
12016         context.SetRegisterPlusOffset(base_reg, address - Rn);
12017         uint64_t data = MemURead(context, address, ebytes, 0, &success);
12018         if (!success)
12019           return false;
12020 
12021         assembled_data =
12022             (data << (e * esize)) |
12023             assembled_data; // New data goes to the left of existing data
12024 
12025         // address = address + ebytes;
12026         address = address + ebytes;
12027       }
12028       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12029                                  assembled_data))
12030         return false;
12031     }
12032   }
12033   return true;
12034 }
12035 
12036 // A8.6.308 VLD1 (single element to one lane)
12037 //
EmulateVLD1Single(const uint32_t opcode,const ARMEncoding encoding)12038 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12039                                               const ARMEncoding encoding) {
12040 #if 0
12041     if ConditionPassed() then
12042         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12043         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12044         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12045         Elem[D[d],index,esize] = MemU[address,ebytes];
12046 #endif
12047 
12048   bool success = false;
12049 
12050   if (ConditionPassed(opcode)) {
12051     uint32_t ebytes;
12052     uint32_t esize;
12053     uint32_t index;
12054     uint32_t alignment;
12055     uint32_t d;
12056     uint32_t n;
12057     uint32_t m;
12058     bool wback;
12059     bool register_index;
12060 
12061     switch (encoding) {
12062     case eEncodingT1:
12063     case eEncodingA1: {
12064       uint32_t size = Bits32(opcode, 11, 10);
12065       uint32_t index_align = Bits32(opcode, 7, 4);
12066       // if size == '11' then SEE VLD1 (single element to all lanes);
12067       if (size == 3)
12068         return EmulateVLD1SingleAll(opcode, encoding);
12069       // case size of
12070       if (size == 0) // when '00'
12071       {
12072         // if index_align<0> != '0' then UNDEFINED;
12073         if (BitIsClear(index_align, 0))
12074           return false;
12075 
12076         // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12077         ebytes = 1;
12078         esize = 8;
12079         index = Bits32(index_align, 3, 1);
12080         alignment = 1;
12081       } else if (size == 1) // when '01'
12082       {
12083         // if index_align<1> != '0' then UNDEFINED;
12084         if (BitIsClear(index_align, 1))
12085           return false;
12086 
12087         // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12088         ebytes = 2;
12089         esize = 16;
12090         index = Bits32(index_align, 3, 2);
12091 
12092         // alignment = if index_align<0> == '0' then 1 else 2;
12093         if (BitIsClear(index_align, 0))
12094           alignment = 1;
12095         else
12096           alignment = 2;
12097       } else if (size == 2) // when '10'
12098       {
12099         // if index_align<2> != '0' then UNDEFINED;
12100         if (BitIsClear(index_align, 2))
12101           return false;
12102 
12103         // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12104         // UNDEFINED;
12105         if ((Bits32(index_align, 1, 0) != 0) &&
12106             (Bits32(index_align, 1, 0) != 3))
12107           return false;
12108 
12109         // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12110         ebytes = 4;
12111         esize = 32;
12112         index = Bit32(index_align, 3);
12113 
12114         // alignment = if index_align<1:0> == '00' then 1 else 4;
12115         if (Bits32(index_align, 1, 0) == 0)
12116           alignment = 1;
12117         else
12118           alignment = 4;
12119       } else {
12120         return false;
12121       }
12122       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12123       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12124       n = Bits32(opcode, 19, 16);
12125       m = Bits32(opcode, 3, 0);
12126 
12127       // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12128       // then UNPREDICTABLE;
12129       wback = (m != 15);
12130       register_index = ((m != 15) && (m != 13));
12131 
12132       if (n == 15)
12133         return false;
12134 
12135     } break;
12136 
12137     default:
12138       return false;
12139     }
12140 
12141     RegisterInfo base_reg;
12142     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12143 
12144     uint32_t Rn = ReadCoreReg(n, &success);
12145     if (!success)
12146       return false;
12147 
12148     // address = R[n]; if (address MOD alignment) != 0 then
12149     // GenerateAlignmentException();
12150     addr_t address = Rn;
12151     if ((address % alignment) != 0)
12152       return false;
12153 
12154     EmulateInstruction::Context context;
12155     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12156     if (wback) {
12157       uint32_t Rm = ReadCoreReg(m, &success);
12158       if (!success)
12159         return false;
12160 
12161       uint32_t offset;
12162       if (register_index)
12163         offset = Rm;
12164       else
12165         offset = ebytes;
12166 
12167       uint32_t value = Rn + offset;
12168 
12169       context.type = eContextAdjustBaseRegister;
12170       context.SetRegisterPlusOffset(base_reg, offset);
12171 
12172       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12173                                  value))
12174         return false;
12175     }
12176 
12177     // Elem[D[d],index,esize] = MemU[address,ebytes];
12178     uint32_t element = MemURead(context, address, esize, 0, &success);
12179     if (!success)
12180       return false;
12181 
12182     element = element << (index * esize);
12183 
12184     uint64_t reg_data =
12185         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12186     if (!success)
12187       return false;
12188 
12189     uint64_t all_ones = -1;
12190     uint64_t mask = all_ones
12191                     << ((index + 1) * esize); // mask is all 1's to left of
12192                                               // where 'element' goes, & all 0's
12193     // at element & to the right of element.
12194     if (index > 0)
12195       mask = mask | Bits64(all_ones, (index * esize) - 1,
12196                            0); // add 1's to the right of where 'element' goes.
12197     // now mask should be 0's where element goes & 1's everywhere else.
12198 
12199     uint64_t masked_reg =
12200         reg_data & mask; // Take original reg value & zero out 'element' bits
12201     reg_data =
12202         masked_reg & element; // Put 'element' into those bits in reg_data.
12203 
12204     context.type = eContextRegisterLoad;
12205     if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12206                                reg_data))
12207       return false;
12208   }
12209   return true;
12210 }
12211 
12212 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12213 // elements) stores elements to memory from one, two, three, or four registers,
12214 // without interleaving.  Every element of each register is stored.
EmulateVST1Multiple(const uint32_t opcode,ARMEncoding encoding)12215 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12216                                                 ARMEncoding encoding) {
12217 #if 0
12218     if ConditionPassed() then
12219         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12220         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12221         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12222         for r = 0 to regs-1
12223             for e = 0 to elements-1
12224                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
12225                 address = address + ebytes;
12226 #endif
12227 
12228   bool success = false;
12229 
12230   if (ConditionPassed(opcode)) {
12231     uint32_t regs;
12232     uint32_t alignment;
12233     uint32_t ebytes;
12234     uint32_t esize;
12235     uint32_t elements;
12236     uint32_t d;
12237     uint32_t n;
12238     uint32_t m;
12239     bool wback;
12240     bool register_index;
12241 
12242     switch (encoding) {
12243     case eEncodingT1:
12244     case eEncodingA1: {
12245       uint32_t type = Bits32(opcode, 11, 8);
12246       uint32_t align = Bits32(opcode, 5, 4);
12247 
12248       // case type of
12249       if (type == 7) // when '0111'
12250       {
12251         // regs = 1; if align<1> == '1' then UNDEFINED;
12252         regs = 1;
12253         if (BitIsSet(align, 1))
12254           return false;
12255       } else if (type == 10) // when '1010'
12256       {
12257         // regs = 2; if align == '11' then UNDEFINED;
12258         regs = 2;
12259         if (align == 3)
12260           return false;
12261       } else if (type == 6) // when '0110'
12262       {
12263         // regs = 3; if align<1> == '1' then UNDEFINED;
12264         regs = 3;
12265         if (BitIsSet(align, 1))
12266           return false;
12267       } else if (type == 2) // when '0010'
12268         // regs = 4;
12269         regs = 4;
12270       else // otherwise
12271         // SEE 'Related encodings';
12272         return false;
12273 
12274       // alignment = if align == '00' then 1 else 4 << UInt(align);
12275       if (align == 0)
12276         alignment = 1;
12277       else
12278         alignment = 4 << align;
12279 
12280       // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12281       ebytes = 1 << Bits32(opcode, 7, 6);
12282       esize = 8 * ebytes;
12283       elements = 8 / ebytes;
12284 
12285       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12286       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12287       n = Bits32(opcode, 19, 16);
12288       m = Bits32(opcode, 3, 0);
12289 
12290       // wback = (m != 15); register_index = (m != 15 && m != 13);
12291       wback = (m != 15);
12292       register_index = ((m != 15) && (m != 13));
12293 
12294       // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12295       if ((d + regs) > 32)
12296         return false;
12297 
12298       if (n == 15)
12299         return false;
12300 
12301     } break;
12302 
12303     default:
12304       return false;
12305     }
12306 
12307     RegisterInfo base_reg;
12308     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12309 
12310     uint32_t Rn = ReadCoreReg(n, &success);
12311     if (!success)
12312       return false;
12313 
12314     // address = R[n]; if (address MOD alignment) != 0 then
12315     // GenerateAlignmentException();
12316     addr_t address = Rn;
12317     if ((address % alignment) != 0)
12318       return false;
12319 
12320     EmulateInstruction::Context context;
12321     // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12322     if (wback) {
12323       uint32_t Rm = ReadCoreReg(m, &success);
12324       if (!success)
12325         return false;
12326 
12327       uint32_t offset;
12328       if (register_index)
12329         offset = Rm;
12330       else
12331         offset = 8 * regs;
12332 
12333       context.type = eContextAdjustBaseRegister;
12334       context.SetRegisterPlusOffset(base_reg, offset);
12335 
12336       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12337                                  Rn + offset))
12338         return false;
12339     }
12340 
12341     RegisterInfo data_reg;
12342     context.type = eContextRegisterStore;
12343     // for r = 0 to regs-1
12344     for (uint32_t r = 0; r < regs; ++r) {
12345       GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12346       uint64_t register_data = ReadRegisterUnsigned(
12347           eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12348       if (!success)
12349         return false;
12350 
12351       // for e = 0 to elements-1
12352       for (uint32_t e = 0; e < elements; ++e) {
12353         // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12354         uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12355 
12356         context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12357                                                 address - Rn);
12358         if (!MemUWrite(context, address, word, ebytes))
12359           return false;
12360 
12361         // address = address + ebytes;
12362         address = address + ebytes;
12363       }
12364     }
12365   }
12366   return true;
12367 }
12368 
12369 // A8.6.392 VST1 (single element from one lane) This instruction stores one
12370 // element to memory from one element of a register.
EmulateVST1Single(const uint32_t opcode,ARMEncoding encoding)12371 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12372                                               ARMEncoding encoding) {
12373 #if 0
12374     if ConditionPassed() then
12375         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12376         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12377         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12378         MemU[address,ebytes] = Elem[D[d],index,esize];
12379 #endif
12380 
12381   bool success = false;
12382 
12383   if (ConditionPassed(opcode)) {
12384     uint32_t ebytes;
12385     uint32_t esize;
12386     uint32_t index;
12387     uint32_t alignment;
12388     uint32_t d;
12389     uint32_t n;
12390     uint32_t m;
12391     bool wback;
12392     bool register_index;
12393 
12394     switch (encoding) {
12395     case eEncodingT1:
12396     case eEncodingA1: {
12397       uint32_t size = Bits32(opcode, 11, 10);
12398       uint32_t index_align = Bits32(opcode, 7, 4);
12399 
12400       // if size == '11' then UNDEFINED;
12401       if (size == 3)
12402         return false;
12403 
12404       // case size of
12405       if (size == 0) // when '00'
12406       {
12407         // if index_align<0> != '0' then UNDEFINED;
12408         if (BitIsClear(index_align, 0))
12409           return false;
12410         // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12411         ebytes = 1;
12412         esize = 8;
12413         index = Bits32(index_align, 3, 1);
12414         alignment = 1;
12415       } else if (size == 1) // when '01'
12416       {
12417         // if index_align<1> != '0' then UNDEFINED;
12418         if (BitIsClear(index_align, 1))
12419           return false;
12420 
12421         // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12422         ebytes = 2;
12423         esize = 16;
12424         index = Bits32(index_align, 3, 2);
12425 
12426         // alignment = if index_align<0> == '0' then 1 else 2;
12427         if (BitIsClear(index_align, 0))
12428           alignment = 1;
12429         else
12430           alignment = 2;
12431       } else if (size == 2) // when '10'
12432       {
12433         // if index_align<2> != '0' then UNDEFINED;
12434         if (BitIsClear(index_align, 2))
12435           return false;
12436 
12437         // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12438         // UNDEFINED;
12439         if ((Bits32(index_align, 1, 0) != 0) &&
12440             (Bits32(index_align, 1, 0) != 3))
12441           return false;
12442 
12443         // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12444         ebytes = 4;
12445         esize = 32;
12446         index = Bit32(index_align, 3);
12447 
12448         // alignment = if index_align<1:0> == '00' then 1 else 4;
12449         if (Bits32(index_align, 1, 0) == 0)
12450           alignment = 1;
12451         else
12452           alignment = 4;
12453       } else {
12454         return false;
12455       }
12456       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12457       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12458       n = Bits32(opcode, 19, 16);
12459       m = Bits32(opcode, 3, 0);
12460 
12461       // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12462       // then UNPREDICTABLE;
12463       wback = (m != 15);
12464       register_index = ((m != 15) && (m != 13));
12465 
12466       if (n == 15)
12467         return false;
12468     } break;
12469 
12470     default:
12471       return false;
12472     }
12473 
12474     RegisterInfo base_reg;
12475     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12476 
12477     uint32_t Rn = ReadCoreReg(n, &success);
12478     if (!success)
12479       return false;
12480 
12481     // address = R[n]; if (address MOD alignment) != 0 then
12482     // GenerateAlignmentException();
12483     addr_t address = Rn;
12484     if ((address % alignment) != 0)
12485       return false;
12486 
12487     EmulateInstruction::Context context;
12488     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12489     if (wback) {
12490       uint32_t Rm = ReadCoreReg(m, &success);
12491       if (!success)
12492         return false;
12493 
12494       uint32_t offset;
12495       if (register_index)
12496         offset = Rm;
12497       else
12498         offset = ebytes;
12499 
12500       context.type = eContextAdjustBaseRegister;
12501       context.SetRegisterPlusOffset(base_reg, offset);
12502 
12503       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12504                                  Rn + offset))
12505         return false;
12506     }
12507 
12508     // MemU[address,ebytes] = Elem[D[d],index,esize];
12509     uint64_t register_data =
12510         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12511     if (!success)
12512       return false;
12513 
12514     uint64_t word =
12515         Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12516 
12517     RegisterInfo data_reg;
12518     GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12519     context.type = eContextRegisterStore;
12520     context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12521 
12522     if (!MemUWrite(context, address, word, ebytes))
12523       return false;
12524   }
12525   return true;
12526 }
12527 
12528 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12529 // element from memory into every element of one or two vectors.
EmulateVLD1SingleAll(const uint32_t opcode,const ARMEncoding encoding)12530 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12531                                                  const ARMEncoding encoding) {
12532 #if 0
12533     if ConditionPassed() then
12534         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12535         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12536         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12537         replicated_element = Replicate(MemU[address,ebytes], elements);
12538         for r = 0 to regs-1
12539             D[d+r] = replicated_element;
12540 #endif
12541 
12542   bool success = false;
12543 
12544   if (ConditionPassed(opcode)) {
12545     uint32_t ebytes;
12546     uint32_t elements;
12547     uint32_t regs;
12548     uint32_t alignment;
12549     uint32_t d;
12550     uint32_t n;
12551     uint32_t m;
12552     bool wback;
12553     bool register_index;
12554 
12555     switch (encoding) {
12556     case eEncodingT1:
12557     case eEncodingA1: {
12558       // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12559       uint32_t size = Bits32(opcode, 7, 6);
12560       if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12561         return false;
12562 
12563       // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12564       // then 1 else 2;
12565       ebytes = 1 << size;
12566       elements = 8 / ebytes;
12567       if (BitIsClear(opcode, 5))
12568         regs = 1;
12569       else
12570         regs = 2;
12571 
12572       // alignment = if a == '0' then 1 else ebytes;
12573       if (BitIsClear(opcode, 4))
12574         alignment = 1;
12575       else
12576         alignment = ebytes;
12577 
12578       // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12579       d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12580       n = Bits32(opcode, 19, 16);
12581       m = Bits32(opcode, 3, 0);
12582 
12583       // wback = (m != 15); register_index = (m != 15 && m != 13);
12584       wback = (m != 15);
12585       register_index = ((m != 15) && (m != 13));
12586 
12587       // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12588       if ((d + regs) > 32)
12589         return false;
12590 
12591       if (n == 15)
12592         return false;
12593     } break;
12594 
12595     default:
12596       return false;
12597     }
12598 
12599     RegisterInfo base_reg;
12600     GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12601 
12602     uint32_t Rn = ReadCoreReg(n, &success);
12603     if (!success)
12604       return false;
12605 
12606     // address = R[n]; if (address MOD alignment) != 0 then
12607     // GenerateAlignmentException();
12608     addr_t address = Rn;
12609     if ((address % alignment) != 0)
12610       return false;
12611 
12612     EmulateInstruction::Context context;
12613     // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12614     if (wback) {
12615       uint32_t Rm = ReadCoreReg(m, &success);
12616       if (!success)
12617         return false;
12618 
12619       uint32_t offset;
12620       if (register_index)
12621         offset = Rm;
12622       else
12623         offset = ebytes;
12624 
12625       context.type = eContextAdjustBaseRegister;
12626       context.SetRegisterPlusOffset(base_reg, offset);
12627 
12628       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12629                                  Rn + offset))
12630         return false;
12631     }
12632 
12633     // replicated_element = Replicate(MemU[address,ebytes], elements);
12634 
12635     context.type = eContextRegisterLoad;
12636     uint64_t word = MemURead(context, address, ebytes, 0, &success);
12637     if (!success)
12638       return false;
12639 
12640     uint64_t replicated_element = 0;
12641     uint32_t esize = ebytes * 8;
12642     for (uint32_t e = 0; e < elements; ++e)
12643       replicated_element =
12644           (replicated_element << esize) | Bits64(word, esize - 1, 0);
12645 
12646     // for r = 0 to regs-1
12647     for (uint32_t r = 0; r < regs; ++r) {
12648       // D[d+r] = replicated_element;
12649       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12650                                  replicated_element))
12651         return false;
12652     }
12653   }
12654   return true;
12655 }
12656 
12657 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12658 // instruction provides an exception return without the use of the stack.  It
12659 // subtracts the immediate constant from the LR, branches to the resulting
12660 // address, and also copies the SPSR to the CPSR.
EmulateSUBSPcLrEtc(const uint32_t opcode,const ARMEncoding encoding)12661 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12662                                                const ARMEncoding encoding) {
12663 #if 0
12664     if ConditionPassed() then
12665         EncodingSpecificOperations();
12666         if CurrentInstrSet() == InstrSet_ThumbEE then
12667             UNPREDICTABLE;
12668         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12669         case opcode of
12670             when '0000' result = R[n] AND operand2; // AND
12671             when '0001' result = R[n] EOR operand2; // EOR
12672             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12673             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12674             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12675             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12676             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12677             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12678             when '1100' result = R[n] OR operand2; // ORR
12679             when '1101' result = operand2; // MOV
12680             when '1110' result = R[n] AND NOT(operand2); // BIC
12681             when '1111' result = NOT(operand2); // MVN
12682         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12683         BranchWritePC(result);
12684 #endif
12685 
12686   bool success = false;
12687 
12688   if (ConditionPassed(opcode)) {
12689     uint32_t n;
12690     uint32_t m;
12691     uint32_t imm32;
12692     bool register_form;
12693     ARM_ShifterType shift_t;
12694     uint32_t shift_n;
12695     uint32_t code;
12696 
12697     switch (encoding) {
12698     case eEncodingT1:
12699       // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12700       // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12701       // // = SUB
12702       n = 14;
12703       imm32 = Bits32(opcode, 7, 0);
12704       register_form = false;
12705       code = 2;
12706 
12707       // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12708       if (InITBlock() && !LastInITBlock())
12709         return false;
12710 
12711       break;
12712 
12713     case eEncodingA1:
12714       // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12715       n = Bits32(opcode, 19, 16);
12716       imm32 = ARMExpandImm(opcode);
12717       register_form = false;
12718       code = Bits32(opcode, 24, 21);
12719 
12720       break;
12721 
12722     case eEncodingA2:
12723       // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12724       n = Bits32(opcode, 19, 16);
12725       m = Bits32(opcode, 3, 0);
12726       register_form = true;
12727 
12728       // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12729       shift_n = DecodeImmShiftARM(opcode, shift_t);
12730 
12731       break;
12732 
12733     default:
12734       return false;
12735     }
12736 
12737     // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12738     // else imm32;
12739     uint32_t operand2;
12740     if (register_form) {
12741       uint32_t Rm = ReadCoreReg(m, &success);
12742       if (!success)
12743         return false;
12744 
12745       operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12746       if (!success)
12747         return false;
12748     } else {
12749       operand2 = imm32;
12750     }
12751 
12752     uint32_t Rn = ReadCoreReg(n, &success);
12753     if (!success)
12754       return false;
12755 
12756     AddWithCarryResult result;
12757 
12758     // case opcode of
12759     switch (code) {
12760     case 0: // when '0000'
12761       // result = R[n] AND operand2; // AND
12762       result.result = Rn & operand2;
12763       break;
12764 
12765     case 1: // when '0001'
12766       // result = R[n] EOR operand2; // EOR
12767       result.result = Rn ^ operand2;
12768       break;
12769 
12770     case 2: // when '0010'
12771       // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12772       result = AddWithCarry(Rn, ~(operand2), 1);
12773       break;
12774 
12775     case 3: // when '0011'
12776       // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12777       result = AddWithCarry(~(Rn), operand2, 1);
12778       break;
12779 
12780     case 4: // when '0100'
12781       // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12782       result = AddWithCarry(Rn, operand2, 0);
12783       break;
12784 
12785     case 5: // when '0101'
12786       // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12787       result = AddWithCarry(Rn, operand2, APSR_C);
12788       break;
12789 
12790     case 6: // when '0110'
12791       // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12792       result = AddWithCarry(Rn, ~(operand2), APSR_C);
12793       break;
12794 
12795     case 7: // when '0111'
12796       // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12797       result = AddWithCarry(~(Rn), operand2, APSR_C);
12798       break;
12799 
12800     case 10: // when '1100'
12801       // result = R[n] OR operand2; // ORR
12802       result.result = Rn | operand2;
12803       break;
12804 
12805     case 11: // when '1101'
12806       // result = operand2; // MOV
12807       result.result = operand2;
12808       break;
12809 
12810     case 12: // when '1110'
12811       // result = R[n] AND NOT(operand2); // BIC
12812       result.result = Rn & ~(operand2);
12813       break;
12814 
12815     case 15: // when '1111'
12816       // result = NOT(operand2); // MVN
12817       result.result = ~(operand2);
12818       break;
12819 
12820     default:
12821       return false;
12822     }
12823     // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12824 
12825     // For now, in emulation mode, we don't have access to the SPSR, so we will
12826     // use the CPSR instead, and hope for the best.
12827     uint32_t spsr =
12828         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12829     if (!success)
12830       return false;
12831 
12832     CPSRWriteByInstr(spsr, 15, true);
12833 
12834     // BranchWritePC(result);
12835     EmulateInstruction::Context context;
12836     context.type = eContextAdjustPC;
12837     context.SetImmediate(result.result);
12838 
12839     BranchWritePC(context, result.result);
12840   }
12841   return true;
12842 }
12843 
12844 EmulateInstructionARM::ARMOpcode *
GetARMOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)12845 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12846                                                   uint32_t arm_isa) {
12847   static ARMOpcode g_arm_opcodes[] = {
12848       // Prologue instructions
12849 
12850       // push register(s)
12851       {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12852        &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12853       {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12854        &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12855 
12856       // set r7 to point to a stack offset
12857       {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12858        &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12859       {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12860        &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12861       // copy the stack pointer to ip
12862       {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12863        &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12864       {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12865        &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12866       {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12867        &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12868 
12869       // adjust the stack pointer
12870       {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12871        &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12872       {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12873        &EmulateInstructionARM::EmulateSUBSPReg,
12874        "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12875 
12876       // push one register
12877       // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12878       {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12879        &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12880 
12881       // vector push consecutive extension register(s)
12882       {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12883        &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12884       {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12885        &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12886 
12887       // Epilogue instructions
12888 
12889       {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12890        &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12891       {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12892        &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12893       {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12894        &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12895       {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12896        &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12897 
12898       // Supervisor Call (previously Software Interrupt)
12899       {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12900        &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12901 
12902       // Branch instructions
12903       // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12904       // "bl <label>".
12905       {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12906        &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12907       {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12908        &EmulateInstructionARM::EmulateB, "b #imm24"},
12909       {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12910        &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12911       {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12912        &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12913       // for example, "bx lr"
12914       {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12915        &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12916       // bxj
12917       {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12918        &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12919 
12920       // Data-processing instructions
12921       // adc (immediate)
12922       {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12923        &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12924       // adc (register)
12925       {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926        &EmulateInstructionARM::EmulateADCReg,
12927        "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12928       // add (immediate)
12929       {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12930        &EmulateInstructionARM::EmulateADDImmARM,
12931        "add{s}<c> <Rd>, <Rn>, #const"},
12932       // add (register)
12933       {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12934        &EmulateInstructionARM::EmulateADDReg,
12935        "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12936       // add (register-shifted register)
12937       {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12938        &EmulateInstructionARM::EmulateADDRegShift,
12939        "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12940       // adr
12941       {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12942        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12943       {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12944        &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12945       // and (immediate)
12946       {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12947        &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12948       // and (register)
12949       {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12950        &EmulateInstructionARM::EmulateANDReg,
12951        "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12952       // bic (immediate)
12953       {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12954        &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12955       // bic (register)
12956       {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12957        &EmulateInstructionARM::EmulateBICReg,
12958        "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12959       // eor (immediate)
12960       {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12961        &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12962       // eor (register)
12963       {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12964        &EmulateInstructionARM::EmulateEORReg,
12965        "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12966       // orr (immediate)
12967       {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12968        &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12969       // orr (register)
12970       {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12971        &EmulateInstructionARM::EmulateORRReg,
12972        "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12973       // rsb (immediate)
12974       {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975        &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12976       // rsb (register)
12977       {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12978        &EmulateInstructionARM::EmulateRSBReg,
12979        "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12980       // rsc (immediate)
12981       {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12982        &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12983       // rsc (register)
12984       {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12985        &EmulateInstructionARM::EmulateRSCReg,
12986        "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12987       // sbc (immediate)
12988       {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12989        &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12990       // sbc (register)
12991       {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12992        &EmulateInstructionARM::EmulateSBCReg,
12993        "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12994       // sub (immediate, ARM)
12995       {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996        &EmulateInstructionARM::EmulateSUBImmARM,
12997        "sub{s}<c> <Rd>, <Rn>, #<const>"},
12998       // sub (sp minus immediate)
12999       {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13000        &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13001       // sub (register)
13002       {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003        &EmulateInstructionARM::EmulateSUBReg,
13004        "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13005       // teq (immediate)
13006       {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13007        &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13008       // teq (register)
13009       {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13010        &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13011       // tst (immediate)
13012       {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13013        &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13014       // tst (register)
13015       {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13016        &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13017 
13018       // mov (immediate)
13019       {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13020        &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13021       {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13022        &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13023       // mov (register)
13024       {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13025        &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13026       // mvn (immediate)
13027       {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13028        &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13029       // mvn (register)
13030       {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13031        &EmulateInstructionARM::EmulateMVNReg,
13032        "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13033       // cmn (immediate)
13034       {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13035        &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13036       // cmn (register)
13037       {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13039       // cmp (immediate)
13040       {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13041        &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13042       // cmp (register)
13043       {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13044        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13045       // asr (immediate)
13046       {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13047        &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13048       // asr (register)
13049       {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13050        &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13051       // lsl (immediate)
13052       {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053        &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13054       // lsl (register)
13055       {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13056        &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13057       // lsr (immediate)
13058       {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059        &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13060       // lsr (register)
13061       {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062        &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13063       // rrx is a special case encoding of ror (immediate)
13064       {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065        &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13066       // ror (immediate)
13067       {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13068        &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13069       // ror (register)
13070       {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13071        &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13072       // mul
13073       {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13074        &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13075 
13076       // subs pc, lr and related instructions
13077       {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13078        &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13079        "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13080       {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13081        &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13082        "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13083 
13084       // Load instructions
13085       {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13086        &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13087       {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13088        &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13089       {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13090        &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13091       {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13092        &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13093       {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13094        &EmulateInstructionARM::EmulateLDRImmediateARM,
13095        "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13096       {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13097        &EmulateInstructionARM::EmulateLDRRegister,
13098        "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13099       {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13100        &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13101       {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13102        &EmulateInstructionARM::EmulateLDRBRegister,
13103        "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13104       {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13105        &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13106       {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13107        &EmulateInstructionARM::EmulateLDRHRegister,
13108        "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13109       {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13110        &EmulateInstructionARM::EmulateLDRSBImmediate,
13111        "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13112       {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13113        &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13114       {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13115        &EmulateInstructionARM::EmulateLDRSBRegister,
13116        "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13117       {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13118        &EmulateInstructionARM::EmulateLDRSHImmediate,
13119        "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13120       {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13121        &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13122       {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13123        &EmulateInstructionARM::EmulateLDRSHRegister,
13124        "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13125       {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13126        &EmulateInstructionARM::EmulateLDRDImmediate,
13127        "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13128       {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13129        &EmulateInstructionARM::EmulateLDRDRegister,
13130        "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13131       {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13132        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13133       {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13134        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13135       {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13136        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13137       {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13138        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13139       {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13140        &EmulateInstructionARM::EmulateVLD1Multiple,
13141        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13142       {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13143        &EmulateInstructionARM::EmulateVLD1Single,
13144        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13145       {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13146        &EmulateInstructionARM::EmulateVLD1SingleAll,
13147        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13148 
13149       // Store instructions
13150       {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13151        &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13152       {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13153        &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13154       {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13155        &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13156       {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13157        &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13158       {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13159        &EmulateInstructionARM::EmulateSTRRegister,
13160        "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13161       {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13162        &EmulateInstructionARM::EmulateSTRHRegister,
13163        "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13164       {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13165        &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13166       {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13167        &EmulateInstructionARM::EmulateSTRBImmARM,
13168        "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13169       {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13170        &EmulateInstructionARM::EmulateSTRImmARM,
13171        "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13172       {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13173        &EmulateInstructionARM::EmulateSTRDImm,
13174        "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13175       {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13176        &EmulateInstructionARM::EmulateSTRDReg,
13177        "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13178       {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13179        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13180       {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13181        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13182       {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13183        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13184       {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13185        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13186       {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13187        &EmulateInstructionARM::EmulateVST1Multiple,
13188        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13189       {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13190        &EmulateInstructionARM::EmulateVST1Single,
13191        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13192 
13193       // Other instructions
13194       {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13195        &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13196       {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13197        &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13198       {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13199        &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13200       {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13201        &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13202       {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13203        &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13204 
13205   };
13206   static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13207 
13208   for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13209     if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13210         (g_arm_opcodes[i].variants & arm_isa) != 0)
13211       return &g_arm_opcodes[i];
13212   }
13213   return nullptr;
13214 }
13215 
13216 EmulateInstructionARM::ARMOpcode *
GetThumbOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)13217 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13218                                                     uint32_t arm_isa) {
13219 
13220   static ARMOpcode g_thumb_opcodes[] = {
13221       // Prologue instructions
13222 
13223       // push register(s)
13224       {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13225        &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13226       {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13227        &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13228       {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13229        &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13230 
13231       // set r7 to point to a stack offset
13232       {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13233        &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13234       // copy the stack pointer to r7
13235       {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13236        &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13237       // move from high register to low register (comes after "mov r7, sp" to
13238       // resolve ambiguity)
13239       {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13240        &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13241 
13242       // PC-relative load into register (see also EmulateADDSPRm)
13243       {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13244        &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13245 
13246       // adjust the stack pointer
13247       {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13248        &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13249       {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13250        &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13251       {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13252        &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13253       {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13254        &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13255       {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13256        &EmulateInstructionARM::EmulateSUBSPReg,
13257        "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13258 
13259       // vector push consecutive extension register(s)
13260       {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13261        &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13262       {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13263        &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13264 
13265       // Epilogue instructions
13266 
13267       {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13268        &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13269       {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13270        &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13271       {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13272        &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13273       {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13274        &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13275       {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13276        &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13277       {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13278        &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13279       {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13280        &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13281 
13282       // Supervisor Call (previously Software Interrupt)
13283       {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13284        &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13285 
13286       // If Then makes up to four following instructions conditional.
13287       // The next 5 opcode _must_ come before the if then instruction
13288       {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13289        &EmulateInstructionARM::EmulateNop, "nop"},
13290       {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13291        &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13292       {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13293        &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13294       {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13295        &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13296       {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13297        &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13298       {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13299        &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13300 
13301       // Branch instructions
13302       // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13303       {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13304        &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13305       {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13306        &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13307       {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13308        &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13309       {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13310        &EmulateInstructionARM::EmulateB,
13311        "b<c>.w #imm8 (outside or last in IT)"},
13312       // J1 == J2 == 1
13313       {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13314        &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13315       // J1 == J2 == 1
13316       {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13317        &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13318       {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13319        &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13320       // for example, "bx lr"
13321       {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13322        &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13323       // bxj
13324       {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13325        &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13326       // compare and branch
13327       {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13328        &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13329       // table branch byte
13330       {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13331        &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13332       // table branch halfword
13333       {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13334        &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13335 
13336       // Data-processing instructions
13337       // adc (immediate)
13338       {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13339        &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13340       // adc (register)
13341       {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13342        &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13343       {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13344        &EmulateInstructionARM::EmulateADCReg,
13345        "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13346       // add (register)
13347       {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13348        &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13349       // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13350       // ambiguity decoding the two.
13351       {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13352        &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13353       // adr
13354       {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13355        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13356       {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13357        &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13358       {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13359        &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13360       // and (immediate)
13361       {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13362        &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13363       // and (register)
13364       {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13365        &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13366       {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13367        &EmulateInstructionARM::EmulateANDReg,
13368        "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13369       // bic (immediate)
13370       {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13371        &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13372       // bic (register)
13373       {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13374        &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13375       {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13376        &EmulateInstructionARM::EmulateBICReg,
13377        "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13378       // eor (immediate)
13379       {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13380        &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13381       // eor (register)
13382       {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13383        &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13384       {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13385        &EmulateInstructionARM::EmulateEORReg,
13386        "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13387       // orr (immediate)
13388       {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13389        &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13390       // orr (register)
13391       {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13392        &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13393       {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13394        &EmulateInstructionARM::EmulateORRReg,
13395        "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13396       // rsb (immediate)
13397       {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13398        &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13399       {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13400        &EmulateInstructionARM::EmulateRSBImm,
13401        "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13402       // rsb (register)
13403       {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13404        &EmulateInstructionARM::EmulateRSBReg,
13405        "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13406       // sbc (immediate)
13407       {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13408        &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13409       // sbc (register)
13410       {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13411        &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13412       {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13413        &EmulateInstructionARM::EmulateSBCReg,
13414        "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13415       // add (immediate, Thumb)
13416       {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13417        &EmulateInstructionARM::EmulateADDImmThumb,
13418        "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13419       {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13420        &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13421       {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13422        &EmulateInstructionARM::EmulateADDImmThumb,
13423        "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13424       {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13425        &EmulateInstructionARM::EmulateADDImmThumb,
13426        "addw<c> <Rd>,<Rn>,#<imm12>"},
13427       // sub (immediate, Thumb)
13428       {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13429        &EmulateInstructionARM::EmulateSUBImmThumb,
13430        "subs|sub<c> <Rd>, <Rn> #imm3"},
13431       {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13432        &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13433       {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13434        &EmulateInstructionARM::EmulateSUBImmThumb,
13435        "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13436       {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13437        &EmulateInstructionARM::EmulateSUBImmThumb,
13438        "subw<c> <Rd>, <Rn>, #imm12"},
13439       // sub (sp minus immediate)
13440       {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13441        &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13442       {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13443        &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13444       // sub (register)
13445       {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13446        &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13447       {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13448        &EmulateInstructionARM::EmulateSUBReg,
13449        "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13450       // teq (immediate)
13451       {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13452        &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13453       // teq (register)
13454       {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13455        &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13456       // tst (immediate)
13457       {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13458        &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13459       // tst (register)
13460       {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13461        &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13462       {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13463        &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13464 
13465       // move from high register to high register
13466       {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13467        &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13468       // move from low register to low register
13469       {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13470        &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13471       // mov{s}<c>.w <Rd>, <Rm>
13472       {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13473        &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13474       // move immediate
13475       {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13476        &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13477       {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13478        &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13479       {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13480        &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13481       // mvn (immediate)
13482       {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13483        &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13484       // mvn (register)
13485       {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13486        &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13487       {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13488        &EmulateInstructionARM::EmulateMVNReg,
13489        "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13490       // cmn (immediate)
13491       {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13492        &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13493       // cmn (register)
13494       {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13495        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13496       {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13497        &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13498       // cmp (immediate)
13499       {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13500        &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13501       {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13502        &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13503       // cmp (register) (Rn and Rm both from r0-r7)
13504       {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13505        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13506       // cmp (register) (Rn and Rm not both from r0-r7)
13507       {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13508        &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13509       {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13510        &EmulateInstructionARM::EmulateCMPReg,
13511        "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13512       // asr (immediate)
13513       {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13514        &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13515       {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13516        &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13517       // asr (register)
13518       {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13519        &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13520       {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13521        &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13522       // lsl (immediate)
13523       {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13524        &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13525       {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13526        &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13527       // lsl (register)
13528       {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13529        &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13530       {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13531        &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13532       // lsr (immediate)
13533       {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13534        &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13535       {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13536        &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13537       // lsr (register)
13538       {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13539        &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13540       {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13541        &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13542       // rrx is a special case encoding of ror (immediate)
13543       {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13544        &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13545       // ror (immediate)
13546       {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13547        &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13548       // ror (register)
13549       {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13550        &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13551       {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13552        &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13553       // mul
13554       {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13555        &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13556       // mul
13557       {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13558        &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13559 
13560       // subs pc, lr and related instructions
13561       {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13562        &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13563 
13564       // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13565       // LDM.. Instructions in this table;
13566       // otherwise the wrong instructions will be selected.
13567 
13568       {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13569        &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13570       {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13571        &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13572 
13573       // Load instructions
13574       {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13575        &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13576       {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13577        &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13578       {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13579        &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13580       {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13581        &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13582       {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13583        &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13584       {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13585        &EmulateInstructionARM::EmulateLDRRtRnImm,
13586        "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13587       {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13588        &EmulateInstructionARM::EmulateLDRRtRnImm,
13589        "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13590       // Thumb2 PC-relative load into register
13591       {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13592        &EmulateInstructionARM::EmulateLDRRtPCRelative,
13593        "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13594       {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13595        &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13596       {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13597        &EmulateInstructionARM::EmulateLDRRegister,
13598        "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13599       {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13600        &EmulateInstructionARM::EmulateLDRBImmediate,
13601        "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13602       {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13603        &EmulateInstructionARM::EmulateLDRBImmediate,
13604        "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13605       {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13606        &EmulateInstructionARM::EmulateLDRBImmediate,
13607        "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13608       {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13609        &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13610       {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13611        &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13612       {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13613        &EmulateInstructionARM::EmulateLDRBRegister,
13614        "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13615       {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13616        &EmulateInstructionARM::EmulateLDRHImmediate,
13617        "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13618       {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13619        &EmulateInstructionARM::EmulateLDRHImmediate,
13620        "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13621       {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13622        &EmulateInstructionARM::EmulateLDRHImmediate,
13623        "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13624       {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13625        &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13626       {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13627        &EmulateInstructionARM::EmulateLDRHRegister,
13628        "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13629       {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13630        &EmulateInstructionARM::EmulateLDRHRegister,
13631        "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13632       {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13633        &EmulateInstructionARM::EmulateLDRSBImmediate,
13634        "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13635       {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13636        &EmulateInstructionARM::EmulateLDRSBImmediate,
13637        "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13638       {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13639        &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13640       {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13641        &EmulateInstructionARM::EmulateLDRSBRegister,
13642        "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13643       {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13644        &EmulateInstructionARM::EmulateLDRSBRegister,
13645        "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13646       {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13647        &EmulateInstructionARM::EmulateLDRSHImmediate,
13648        "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13649       {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13650        &EmulateInstructionARM::EmulateLDRSHImmediate,
13651        "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13652       {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13653        &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13654       {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13655        &EmulateInstructionARM::EmulateLDRSHRegister,
13656        "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13657       {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13658        &EmulateInstructionARM::EmulateLDRSHRegister,
13659        "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13660       {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13661        &EmulateInstructionARM::EmulateLDRDImmediate,
13662        "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13663       {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13664        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13665       {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13666        &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13667       {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13668        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13669       {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13670        &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13671       {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13672        &EmulateInstructionARM::EmulateVLD1Multiple,
13673        "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13674       {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13675        &EmulateInstructionARM::EmulateVLD1Single,
13676        "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13677       {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13678        &EmulateInstructionARM::EmulateVLD1SingleAll,
13679        "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13680 
13681       // Store instructions
13682       {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13683        &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13684       {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13685        &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13686       {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13687        &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13688       {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13689        &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13690       {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13691        &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13692       {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13693        &EmulateInstructionARM::EmulateSTRThumb,
13694        "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13695       {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13696        &EmulateInstructionARM::EmulateSTRThumb,
13697        "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13698       {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13699        &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13700       {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13701        &EmulateInstructionARM::EmulateSTRRegister,
13702        "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13703       {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13704        &EmulateInstructionARM::EmulateSTRBThumb,
13705        "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13706       {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13707        &EmulateInstructionARM::EmulateSTRBThumb,
13708        "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13709       {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13710        &EmulateInstructionARM::EmulateSTRBThumb,
13711        "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13712       {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13713        &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13714       {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13715        &EmulateInstructionARM::EmulateSTRHRegister,
13716        "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13717       {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13718        &EmulateInstructionARM::EmulateSTREX,
13719        "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13720       {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13721        &EmulateInstructionARM::EmulateSTRDImm,
13722        "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13723       {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13724        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13725       {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13726        &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13727       {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13728        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13729       {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13730        &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13731       {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13732        &EmulateInstructionARM::EmulateVST1Multiple,
13733        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13734       {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13735        &EmulateInstructionARM::EmulateVST1Single,
13736        "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13737 
13738       // Other instructions
13739       {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13740        &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13741       {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13742        &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13743       {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13744        &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13745       {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13746        &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13747       {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13748        &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13749       {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13750        &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13751       {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13752        &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13753       {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13754        &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13755   };
13756 
13757   const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13758   for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13759     if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13760         (g_thumb_opcodes[i].variants & arm_isa) != 0)
13761       return &g_thumb_opcodes[i];
13762   }
13763   return nullptr;
13764 }
13765 
SetArchitecture(const ArchSpec & arch)13766 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13767   m_arch = arch;
13768   m_arm_isa = 0;
13769   const char *arch_cstr = arch.GetArchitectureName();
13770   if (arch_cstr) {
13771     if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13772       m_arm_isa = ARMv4T;
13773     else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13774       m_arm_isa = ARMv5TEJ;
13775     else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13776       m_arm_isa = ARMv5TE;
13777     else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13778       m_arm_isa = ARMv5T;
13779     else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13780       m_arm_isa = ARMv6K;
13781     else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13782       m_arm_isa = ARMv6T2;
13783     else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13784       m_arm_isa = ARMv7S;
13785     else if (0 == ::strcasecmp(arch_cstr, "arm"))
13786       m_arm_isa = ARMvAll;
13787     else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13788       m_arm_isa = ARMvAll;
13789     else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13790       m_arm_isa = ARMv4;
13791     else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13792       m_arm_isa = ARMv6;
13793     else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13794       m_arm_isa = ARMv7;
13795     else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13796       m_arm_isa = ARMv8;
13797   }
13798   return m_arm_isa != 0;
13799 }
13800 
SetInstruction(const Opcode & insn_opcode,const Address & inst_addr,Target * target)13801 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13802                                            const Address &inst_addr,
13803                                            Target *target) {
13804   if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13805     if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13806         m_arch.IsAlwaysThumbInstructions())
13807       m_opcode_mode = eModeThumb;
13808     else {
13809       AddressClass addr_class = inst_addr.GetAddressClass();
13810 
13811       if ((addr_class == AddressClass::eCode) ||
13812           (addr_class == AddressClass::eUnknown))
13813         m_opcode_mode = eModeARM;
13814       else if (addr_class == AddressClass::eCodeAlternateISA)
13815         m_opcode_mode = eModeThumb;
13816       else
13817         return false;
13818     }
13819     if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13820       m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13821     else
13822       m_opcode_cpsr = CPSR_MODE_USR;
13823     return true;
13824   }
13825   return false;
13826 }
13827 
ReadInstruction()13828 bool EmulateInstructionARM::ReadInstruction() {
13829   bool success = false;
13830   m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13831                                        LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13832   if (success) {
13833     addr_t pc =
13834         ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13835                              LLDB_INVALID_ADDRESS, &success);
13836     if (success) {
13837       Context read_inst_context;
13838       read_inst_context.type = eContextReadOpcode;
13839       read_inst_context.SetNoArgs();
13840 
13841       if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13842         m_opcode_mode = eModeThumb;
13843         uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13844 
13845         if (success) {
13846           if ((thumb_opcode & 0xe000) != 0xe000 ||
13847               ((thumb_opcode & 0x1800u) == 0)) {
13848             m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13849           } else {
13850             m_opcode.SetOpcode32(
13851                 (thumb_opcode << 16) |
13852                     MemARead(read_inst_context, pc + 2, 2, 0, &success),
13853                 GetByteOrder());
13854           }
13855         }
13856       } else {
13857         m_opcode_mode = eModeARM;
13858         m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13859                              GetByteOrder());
13860       }
13861 
13862       if (!m_ignore_conditions) {
13863         // If we are not ignoreing the conditions then init the it session from
13864         // the current value of cpsr.
13865         uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13866                       Bits32(m_opcode_cpsr, 26, 25);
13867         if (it != 0)
13868           m_it_session.InitIT(it);
13869       }
13870     }
13871   }
13872   if (!success) {
13873     m_opcode_mode = eModeInvalid;
13874     m_addr = LLDB_INVALID_ADDRESS;
13875   }
13876   return success;
13877 }
13878 
ArchVersion()13879 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13880 
ConditionPassed(const uint32_t opcode)13881 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13882   // If we are ignoring conditions, then always return true. this allows us to
13883   // iterate over disassembly code and still emulate an instruction even if we
13884   // don't have all the right bits set in the CPSR register...
13885   if (m_ignore_conditions)
13886     return true;
13887 
13888   const uint32_t cond = CurrentCond(opcode);
13889   if (cond == UINT32_MAX)
13890     return false;
13891 
13892   bool result = false;
13893   switch (UnsignedBits(cond, 3, 1)) {
13894   case 0:
13895     if (m_opcode_cpsr == 0)
13896       result = true;
13897     else
13898       result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13899     break;
13900   case 1:
13901     if (m_opcode_cpsr == 0)
13902       result = true;
13903     else
13904       result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13905     break;
13906   case 2:
13907     if (m_opcode_cpsr == 0)
13908       result = true;
13909     else
13910       result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13911     break;
13912   case 3:
13913     if (m_opcode_cpsr == 0)
13914       result = true;
13915     else
13916       result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13917     break;
13918   case 4:
13919     if (m_opcode_cpsr == 0)
13920       result = true;
13921     else
13922       result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13923                ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13924     break;
13925   case 5:
13926     if (m_opcode_cpsr == 0)
13927       result = true;
13928     else {
13929       bool n = (m_opcode_cpsr & MASK_CPSR_N);
13930       bool v = (m_opcode_cpsr & MASK_CPSR_V);
13931       result = n == v;
13932     }
13933     break;
13934   case 6:
13935     if (m_opcode_cpsr == 0)
13936       result = true;
13937     else {
13938       bool n = (m_opcode_cpsr & MASK_CPSR_N);
13939       bool v = (m_opcode_cpsr & MASK_CPSR_V);
13940       result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13941     }
13942     break;
13943   case 7:
13944     // Always execute (cond == 0b1110, or the special 0b1111 which gives
13945     // opcodes different meanings, but always means execution happens.
13946     return true;
13947   }
13948 
13949   if (cond & 1)
13950     result = !result;
13951   return result;
13952 }
13953 
CurrentCond(const uint32_t opcode)13954 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13955   switch (m_opcode_mode) {
13956   case eModeInvalid:
13957     break;
13958 
13959   case eModeARM:
13960     return UnsignedBits(opcode, 31, 28);
13961 
13962   case eModeThumb:
13963     // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13964     // 'cond' field of the encoding.
13965     {
13966       const uint32_t byte_size = m_opcode.GetByteSize();
13967       if (byte_size == 2) {
13968         if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13969           return Bits32(opcode, 11, 8);
13970       } else if (byte_size == 4) {
13971         if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13972             Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13973           return Bits32(opcode, 25, 22);
13974         }
13975       } else
13976         // We have an invalid thumb instruction, let's bail out.
13977         break;
13978 
13979       return m_it_session.GetCond();
13980     }
13981   }
13982   return UINT32_MAX; // Return invalid value
13983 }
13984 
InITBlock()13985 bool EmulateInstructionARM::InITBlock() {
13986   return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13987 }
13988 
LastInITBlock()13989 bool EmulateInstructionARM::LastInITBlock() {
13990   return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13991 }
13992 
BadMode(uint32_t mode)13993 bool EmulateInstructionARM::BadMode(uint32_t mode) {
13994 
13995   switch (mode) {
13996   case 16:
13997     return false; // '10000'
13998   case 17:
13999     return false; // '10001'
14000   case 18:
14001     return false; // '10010'
14002   case 19:
14003     return false; // '10011'
14004   case 22:
14005     return false; // '10110'
14006   case 23:
14007     return false; // '10111'
14008   case 27:
14009     return false; // '11011'
14010   case 31:
14011     return false; // '11111'
14012   default:
14013     return true;
14014   }
14015   return true;
14016 }
14017 
CurrentModeIsPrivileged()14018 bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14019   uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14020 
14021   if (BadMode(mode))
14022     return false;
14023 
14024   if (mode == 16)
14025     return false;
14026 
14027   return true;
14028 }
14029 
CPSRWriteByInstr(uint32_t value,uint32_t bytemask,bool affect_execstate)14030 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14031                                              bool affect_execstate) {
14032   bool privileged = CurrentModeIsPrivileged();
14033 
14034   uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14035 
14036   if (BitIsSet(bytemask, 3)) {
14037     tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14038     if (affect_execstate)
14039       tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14040   }
14041 
14042   if (BitIsSet(bytemask, 2)) {
14043     tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14044   }
14045 
14046   if (BitIsSet(bytemask, 1)) {
14047     if (affect_execstate)
14048       tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14049     tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14050     if (privileged)
14051       tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14052   }
14053 
14054   if (BitIsSet(bytemask, 0)) {
14055     if (privileged)
14056       tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14057     if (affect_execstate)
14058       tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14059     if (privileged)
14060       tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14061   }
14062 
14063   m_opcode_cpsr = tmp_cpsr;
14064 }
14065 
BranchWritePC(const Context & context,uint32_t addr)14066 bool EmulateInstructionARM::BranchWritePC(const Context &context,
14067                                           uint32_t addr) {
14068   addr_t target;
14069 
14070   // Check the current instruction set.
14071   if (CurrentInstrSet() == eModeARM)
14072     target = addr & 0xfffffffc;
14073   else
14074     target = addr & 0xfffffffe;
14075 
14076   return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14077                                LLDB_REGNUM_GENERIC_PC, target);
14078 }
14079 
14080 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14081 // inspecting addr.
BXWritePC(Context & context,uint32_t addr)14082 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14083   addr_t target;
14084   // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14085   // we want to record it and issue a WriteRegister callback so the clients can
14086   // track the mode changes accordingly.
14087   bool cpsr_changed = false;
14088 
14089   if (BitIsSet(addr, 0)) {
14090     if (CurrentInstrSet() != eModeThumb) {
14091       SelectInstrSet(eModeThumb);
14092       cpsr_changed = true;
14093     }
14094     target = addr & 0xfffffffe;
14095     context.SetISA(eModeThumb);
14096   } else if (BitIsClear(addr, 1)) {
14097     if (CurrentInstrSet() != eModeARM) {
14098       SelectInstrSet(eModeARM);
14099       cpsr_changed = true;
14100     }
14101     target = addr & 0xfffffffc;
14102     context.SetISA(eModeARM);
14103   } else
14104     return false; // address<1:0> == '10' => UNPREDICTABLE
14105 
14106   if (cpsr_changed) {
14107     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14108                                LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14109       return false;
14110   }
14111   return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14112                                LLDB_REGNUM_GENERIC_PC, target);
14113 }
14114 
14115 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14116 // versions.
LoadWritePC(Context & context,uint32_t addr)14117 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14118   if (ArchVersion() >= ARMv5T)
14119     return BXWritePC(context, addr);
14120   else
14121     return BranchWritePC((const Context)context, addr);
14122 }
14123 
14124 // Dispatches to either BXWritePC or BranchWritePC based on architecture
14125 // versions and current instruction set.
ALUWritePC(Context & context,uint32_t addr)14126 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14127   if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14128     return BXWritePC(context, addr);
14129   else
14130     return BranchWritePC((const Context)context, addr);
14131 }
14132 
CurrentInstrSet()14133 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14134   return m_opcode_mode;
14135 }
14136 
14137 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14138 // ReadInstruction() is performed.  This function has a side effect of updating
14139 // the m_new_inst_cpsr member variable if necessary.
SelectInstrSet(Mode arm_or_thumb)14140 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14141   m_new_inst_cpsr = m_opcode_cpsr;
14142   switch (arm_or_thumb) {
14143   default:
14144     return false;
14145   case eModeARM:
14146     // Clear the T bit.
14147     m_new_inst_cpsr &= ~MASK_CPSR_T;
14148     break;
14149   case eModeThumb:
14150     // Set the T bit.
14151     m_new_inst_cpsr |= MASK_CPSR_T;
14152     break;
14153   }
14154   return true;
14155 }
14156 
14157 // This function returns TRUE if the processor currently provides support for
14158 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14159 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
UnalignedSupport()14160 bool EmulateInstructionARM::UnalignedSupport() {
14161   return (ArchVersion() >= ARMv7);
14162 }
14163 
14164 // The main addition and subtraction instructions can produce status
14165 // information about both unsigned carry and signed overflow conditions.  This
14166 // status information can be used to synthesize multi-word additions and
14167 // subtractions.
14168 EmulateInstructionARM::AddWithCarryResult
AddWithCarry(uint32_t x,uint32_t y,uint8_t carry_in)14169 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14170   uint32_t result;
14171   uint8_t carry_out;
14172   uint8_t overflow;
14173 
14174   uint64_t unsigned_sum = x + y + carry_in;
14175   int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14176 
14177   result = UnsignedBits(unsigned_sum, 31, 0);
14178   //    carry_out = (result == unsigned_sum ? 0 : 1);
14179   overflow = ((int32_t)result == signed_sum ? 0 : 1);
14180 
14181   if (carry_in)
14182     carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14183   else
14184     carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14185 
14186   AddWithCarryResult res = {result, carry_out, overflow};
14187   return res;
14188 }
14189 
ReadCoreReg(uint32_t num,bool * success)14190 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14191   lldb::RegisterKind reg_kind;
14192   uint32_t reg_num;
14193   switch (num) {
14194   case SP_REG:
14195     reg_kind = eRegisterKindGeneric;
14196     reg_num = LLDB_REGNUM_GENERIC_SP;
14197     break;
14198   case LR_REG:
14199     reg_kind = eRegisterKindGeneric;
14200     reg_num = LLDB_REGNUM_GENERIC_RA;
14201     break;
14202   case PC_REG:
14203     reg_kind = eRegisterKindGeneric;
14204     reg_num = LLDB_REGNUM_GENERIC_PC;
14205     break;
14206   default:
14207     if (num < SP_REG) {
14208       reg_kind = eRegisterKindDWARF;
14209       reg_num = dwarf_r0 + num;
14210     } else {
14211       // assert(0 && "Invalid register number");
14212       *success = false;
14213       return UINT32_MAX;
14214     }
14215     break;
14216   }
14217 
14218   // Read our register.
14219   uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14220 
14221   // When executing an ARM instruction , PC reads as the address of the current
14222   // instruction plus 8. When executing a Thumb instruction , PC reads as the
14223   // address of the current instruction plus 4.
14224   if (num == 15) {
14225     if (CurrentInstrSet() == eModeARM)
14226       val += 8;
14227     else
14228       val += 4;
14229   }
14230 
14231   return val;
14232 }
14233 
14234 // Write the result to the ARM core register Rd, and optionally update the
14235 // condition flags based on the result.
14236 //
14237 // This helper method tries to encapsulate the following pseudocode from the
14238 // ARM Architecture Reference Manual:
14239 //
14240 // if d == 15 then         // Can only occur for encoding A1
14241 //     ALUWritePC(result); // setflags is always FALSE here
14242 // else
14243 //     R[d] = result;
14244 //     if setflags then
14245 //         APSR.N = result<31>;
14246 //         APSR.Z = IsZeroBit(result);
14247 //         APSR.C = carry;
14248 //         // APSR.V unchanged
14249 //
14250 // In the above case, the API client does not pass in the overflow arg, which
14251 // defaults to ~0u.
WriteCoreRegOptionalFlags(Context & context,const uint32_t result,const uint32_t Rd,bool setflags,const uint32_t carry,const uint32_t overflow)14252 bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14253     Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14254     const uint32_t carry, const uint32_t overflow) {
14255   if (Rd == 15) {
14256     if (!ALUWritePC(context, result))
14257       return false;
14258   } else {
14259     lldb::RegisterKind reg_kind;
14260     uint32_t reg_num;
14261     switch (Rd) {
14262     case SP_REG:
14263       reg_kind = eRegisterKindGeneric;
14264       reg_num = LLDB_REGNUM_GENERIC_SP;
14265       break;
14266     case LR_REG:
14267       reg_kind = eRegisterKindGeneric;
14268       reg_num = LLDB_REGNUM_GENERIC_RA;
14269       break;
14270     default:
14271       reg_kind = eRegisterKindDWARF;
14272       reg_num = dwarf_r0 + Rd;
14273     }
14274     if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14275       return false;
14276     if (setflags)
14277       return WriteFlags(context, result, carry, overflow);
14278   }
14279   return true;
14280 }
14281 
14282 // This helper method tries to encapsulate the following pseudocode from the
14283 // ARM Architecture Reference Manual:
14284 //
14285 // APSR.N = result<31>;
14286 // APSR.Z = IsZeroBit(result);
14287 // APSR.C = carry;
14288 // APSR.V = overflow
14289 //
14290 // Default arguments can be specified for carry and overflow parameters, which
14291 // means not to update the respective flags.
WriteFlags(Context & context,const uint32_t result,const uint32_t carry,const uint32_t overflow)14292 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14293                                        const uint32_t carry,
14294                                        const uint32_t overflow) {
14295   m_new_inst_cpsr = m_opcode_cpsr;
14296   SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14297   SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14298   if (carry != ~0u)
14299     SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14300   if (overflow != ~0u)
14301     SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14302   if (m_new_inst_cpsr != m_opcode_cpsr) {
14303     if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14304                                LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14305       return false;
14306   }
14307   return true;
14308 }
14309 
EvaluateInstruction(uint32_t evaluate_options)14310 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14311   ARMOpcode *opcode_data = nullptr;
14312 
14313   if (m_opcode_mode == eModeThumb)
14314     opcode_data =
14315         GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14316   else if (m_opcode_mode == eModeARM)
14317     opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14318 
14319   const bool auto_advance_pc =
14320       evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14321   m_ignore_conditions =
14322       evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14323 
14324   bool success = false;
14325   if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14326     m_opcode_cpsr =
14327         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14328   }
14329 
14330   // Only return false if we are unable to read the CPSR if we care about
14331   // conditions
14332   if (!success && !m_ignore_conditions)
14333     return false;
14334 
14335   uint32_t orig_pc_value = 0;
14336   if (auto_advance_pc) {
14337     orig_pc_value =
14338         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14339     if (!success)
14340       return false;
14341   }
14342 
14343   // Call the Emulate... function if we managed to decode the opcode.
14344   if (opcode_data) {
14345     success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14346                                              opcode_data->encoding);
14347     if (!success)
14348       return false;
14349   }
14350 
14351   // Advance the ITSTATE bits to their values for the next instruction if we
14352   // haven't just executed an IT instruction what initialized it.
14353   if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14354       (opcode_data == nullptr ||
14355        opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14356     m_it_session.ITAdvance();
14357 
14358   if (auto_advance_pc) {
14359     uint32_t after_pc_value =
14360         ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14361     if (!success)
14362       return false;
14363 
14364     if (after_pc_value == orig_pc_value) {
14365       after_pc_value += m_opcode.GetByteSize();
14366 
14367       EmulateInstruction::Context context;
14368       context.type = eContextAdvancePC;
14369       context.SetNoArgs();
14370       if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14371                                  after_pc_value))
14372         return false;
14373     }
14374   }
14375   return true;
14376 }
14377 
14378 EmulateInstruction::InstructionCondition
GetInstructionCondition()14379 EmulateInstructionARM::GetInstructionCondition() {
14380   const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14381   if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14382     return EmulateInstruction::UnconditionalCondition;
14383   return cond;
14384 }
14385 
TestEmulation(Stream * out_stream,ArchSpec & arch,OptionValueDictionary * test_data)14386 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14387                                           OptionValueDictionary *test_data) {
14388   if (!test_data) {
14389     out_stream->Printf("TestEmulation: Missing test data.\n");
14390     return false;
14391   }
14392 
14393   static ConstString opcode_key("opcode");
14394   static ConstString before_key("before_state");
14395   static ConstString after_key("after_state");
14396 
14397   OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14398 
14399   uint32_t test_opcode;
14400   if ((value_sp.get() == nullptr) ||
14401       (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14402     out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14403     return false;
14404   }
14405   test_opcode = value_sp->GetUInt64Value();
14406 
14407   if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14408       arch.IsAlwaysThumbInstructions()) {
14409     m_opcode_mode = eModeThumb;
14410     if (test_opcode < 0x10000)
14411       m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14412     else
14413       m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14414   } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14415     m_opcode_mode = eModeARM;
14416     m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14417   } else {
14418     out_stream->Printf("TestEmulation:  Invalid arch.\n");
14419     return false;
14420   }
14421 
14422   EmulationStateARM before_state;
14423   EmulationStateARM after_state;
14424 
14425   value_sp = test_data->GetValueForKey(before_key);
14426   if ((value_sp.get() == nullptr) ||
14427       (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14428     out_stream->Printf("TestEmulation:  Failed to find 'before' state.\n");
14429     return false;
14430   }
14431 
14432   OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14433   if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14434     out_stream->Printf("TestEmulation:  Failed loading 'before' state.\n");
14435     return false;
14436   }
14437 
14438   value_sp = test_data->GetValueForKey(after_key);
14439   if ((value_sp.get() == nullptr) ||
14440       (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14441     out_stream->Printf("TestEmulation:  Failed to find 'after' state.\n");
14442     return false;
14443   }
14444 
14445   state_dictionary = value_sp->GetAsDictionary();
14446   if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14447     out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14448     return false;
14449   }
14450 
14451   SetBaton((void *)&before_state);
14452   SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14453                &EmulationStateARM::WritePseudoMemory,
14454                &EmulationStateARM::ReadPseudoRegister,
14455                &EmulationStateARM::WritePseudoRegister);
14456 
14457   bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14458   if (!success) {
14459     out_stream->Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14460     return false;
14461   }
14462 
14463   success = before_state.CompareState(after_state);
14464   if (!success)
14465     out_stream->Printf(
14466         "TestEmulation:  'before' and 'after' states do not match.\n");
14467 
14468   return success;
14469 }
14470 //
14471 //
14472 // const char *
14473 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14474 //{
14475 //    if (reg_kind == eRegisterKindGeneric)
14476 //    {
14477 //        switch (reg_num)
14478 //        {
14479 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14480 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14481 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14482 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14483 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14484 //        default: return NULL;
14485 //        }
14486 //    }
14487 //    else if (reg_kind == eRegisterKindDWARF)
14488 //    {
14489 //        return GetARMDWARFRegisterName (reg_num);
14490 //    }
14491 //    return NULL;
14492 //}
14493 //
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)14494 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14495   unwind_plan.Clear();
14496   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14497 
14498   UnwindPlan::RowSP row(new UnwindPlan::Row);
14499 
14500   // Our previous Call Frame Address is the stack pointer
14501   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14502 
14503   unwind_plan.AppendRow(row);
14504   unwind_plan.SetSourceName("EmulateInstructionARM");
14505   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14506   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14507   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
14508   unwind_plan.SetReturnAddressRegister(dwarf_lr);
14509   return true;
14510 }
14511