EmulateInstructionARM.cpp revision 321369
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdlib.h>
11
12#include "EmulateInstructionARM.h"
13#include "EmulationStateARM.h"
14#include "lldb/Core/Address.h"
15#include "lldb/Core/ArchSpec.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Host/PosixApi.h"
18#include "lldb/Interpreter/OptionValueArray.h"
19#include "lldb/Interpreter/OptionValueDictionary.h"
20#include "lldb/Symbol/UnwindPlan.h"
21#include "lldb/Utility/ConstString.h"
22#include "lldb/Utility/Stream.h"
23
24#include "Plugins/Process/Utility/ARMDefines.h"
25#include "Plugins/Process/Utility/ARMUtils.h"
26#include "Utility/ARM_DWARF_Registers.h"
27
28#include "llvm/ADT/STLExtras.h"
29#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
30                                     // and countTrailingZeros function
31
32using namespace lldb;
33using namespace lldb_private;
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//
43// ITSession implementation
44//
45//----------------------------------------------------------------------
46
47static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo &reg_info) {
48  ::memset(&reg_info, 0, sizeof(RegisterInfo));
49  ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
50
51  if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
52    reg_info.byte_size = 16;
53    reg_info.format = eFormatVectorOfUInt8;
54    reg_info.encoding = eEncodingVector;
55  }
56
57  if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
58    reg_info.byte_size = 8;
59    reg_info.format = eFormatFloat;
60    reg_info.encoding = eEncodingIEEE754;
61  } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
62    reg_info.byte_size = 4;
63    reg_info.format = eFormatFloat;
64    reg_info.encoding = eEncodingIEEE754;
65  } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
66    reg_info.byte_size = 12;
67    reg_info.format = eFormatFloat;
68    reg_info.encoding = eEncodingIEEE754;
69  } else {
70    reg_info.byte_size = 4;
71    reg_info.format = eFormatHex;
72    reg_info.encoding = eEncodingUint;
73  }
74
75  reg_info.kinds[eRegisterKindDWARF] = reg_num;
76
77  switch (reg_num) {
78  case dwarf_r0:
79    reg_info.name = "r0";
80    break;
81  case dwarf_r1:
82    reg_info.name = "r1";
83    break;
84  case dwarf_r2:
85    reg_info.name = "r2";
86    break;
87  case dwarf_r3:
88    reg_info.name = "r3";
89    break;
90  case dwarf_r4:
91    reg_info.name = "r4";
92    break;
93  case dwarf_r5:
94    reg_info.name = "r5";
95    break;
96  case dwarf_r6:
97    reg_info.name = "r6";
98    break;
99  case dwarf_r7:
100    reg_info.name = "r7";
101    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
102    break;
103  case dwarf_r8:
104    reg_info.name = "r8";
105    break;
106  case dwarf_r9:
107    reg_info.name = "r9";
108    break;
109  case dwarf_r10:
110    reg_info.name = "r10";
111    break;
112  case dwarf_r11:
113    reg_info.name = "r11";
114    break;
115  case dwarf_r12:
116    reg_info.name = "r12";
117    break;
118  case dwarf_sp:
119    reg_info.name = "sp";
120    reg_info.alt_name = "r13";
121    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
122    break;
123  case dwarf_lr:
124    reg_info.name = "lr";
125    reg_info.alt_name = "r14";
126    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
127    break;
128  case dwarf_pc:
129    reg_info.name = "pc";
130    reg_info.alt_name = "r15";
131    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
132    break;
133  case dwarf_cpsr:
134    reg_info.name = "cpsr";
135    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
136    break;
137
138  case dwarf_s0:
139    reg_info.name = "s0";
140    break;
141  case dwarf_s1:
142    reg_info.name = "s1";
143    break;
144  case dwarf_s2:
145    reg_info.name = "s2";
146    break;
147  case dwarf_s3:
148    reg_info.name = "s3";
149    break;
150  case dwarf_s4:
151    reg_info.name = "s4";
152    break;
153  case dwarf_s5:
154    reg_info.name = "s5";
155    break;
156  case dwarf_s6:
157    reg_info.name = "s6";
158    break;
159  case dwarf_s7:
160    reg_info.name = "s7";
161    break;
162  case dwarf_s8:
163    reg_info.name = "s8";
164    break;
165  case dwarf_s9:
166    reg_info.name = "s9";
167    break;
168  case dwarf_s10:
169    reg_info.name = "s10";
170    break;
171  case dwarf_s11:
172    reg_info.name = "s11";
173    break;
174  case dwarf_s12:
175    reg_info.name = "s12";
176    break;
177  case dwarf_s13:
178    reg_info.name = "s13";
179    break;
180  case dwarf_s14:
181    reg_info.name = "s14";
182    break;
183  case dwarf_s15:
184    reg_info.name = "s15";
185    break;
186  case dwarf_s16:
187    reg_info.name = "s16";
188    break;
189  case dwarf_s17:
190    reg_info.name = "s17";
191    break;
192  case dwarf_s18:
193    reg_info.name = "s18";
194    break;
195  case dwarf_s19:
196    reg_info.name = "s19";
197    break;
198  case dwarf_s20:
199    reg_info.name = "s20";
200    break;
201  case dwarf_s21:
202    reg_info.name = "s21";
203    break;
204  case dwarf_s22:
205    reg_info.name = "s22";
206    break;
207  case dwarf_s23:
208    reg_info.name = "s23";
209    break;
210  case dwarf_s24:
211    reg_info.name = "s24";
212    break;
213  case dwarf_s25:
214    reg_info.name = "s25";
215    break;
216  case dwarf_s26:
217    reg_info.name = "s26";
218    break;
219  case dwarf_s27:
220    reg_info.name = "s27";
221    break;
222  case dwarf_s28:
223    reg_info.name = "s28";
224    break;
225  case dwarf_s29:
226    reg_info.name = "s29";
227    break;
228  case dwarf_s30:
229    reg_info.name = "s30";
230    break;
231  case dwarf_s31:
232    reg_info.name = "s31";
233    break;
234
235  // FPA Registers 0-7
236  case dwarf_f0:
237    reg_info.name = "f0";
238    break;
239  case dwarf_f1:
240    reg_info.name = "f1";
241    break;
242  case dwarf_f2:
243    reg_info.name = "f2";
244    break;
245  case dwarf_f3:
246    reg_info.name = "f3";
247    break;
248  case dwarf_f4:
249    reg_info.name = "f4";
250    break;
251  case dwarf_f5:
252    reg_info.name = "f5";
253    break;
254  case dwarf_f6:
255    reg_info.name = "f6";
256    break;
257  case dwarf_f7:
258    reg_info.name = "f7";
259    break;
260
261  // Intel wireless MMX general purpose registers 0 - 7
262  // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
263  case dwarf_wCGR0:
264    reg_info.name = "wCGR0/ACC0";
265    break;
266  case dwarf_wCGR1:
267    reg_info.name = "wCGR1/ACC1";
268    break;
269  case dwarf_wCGR2:
270    reg_info.name = "wCGR2/ACC2";
271    break;
272  case dwarf_wCGR3:
273    reg_info.name = "wCGR3/ACC3";
274    break;
275  case dwarf_wCGR4:
276    reg_info.name = "wCGR4/ACC4";
277    break;
278  case dwarf_wCGR5:
279    reg_info.name = "wCGR5/ACC5";
280    break;
281  case dwarf_wCGR6:
282    reg_info.name = "wCGR6/ACC6";
283    break;
284  case dwarf_wCGR7:
285    reg_info.name = "wCGR7/ACC7";
286    break;
287
288  // Intel wireless MMX data registers 0 - 15
289  case dwarf_wR0:
290    reg_info.name = "wR0";
291    break;
292  case dwarf_wR1:
293    reg_info.name = "wR1";
294    break;
295  case dwarf_wR2:
296    reg_info.name = "wR2";
297    break;
298  case dwarf_wR3:
299    reg_info.name = "wR3";
300    break;
301  case dwarf_wR4:
302    reg_info.name = "wR4";
303    break;
304  case dwarf_wR5:
305    reg_info.name = "wR5";
306    break;
307  case dwarf_wR6:
308    reg_info.name = "wR6";
309    break;
310  case dwarf_wR7:
311    reg_info.name = "wR7";
312    break;
313  case dwarf_wR8:
314    reg_info.name = "wR8";
315    break;
316  case dwarf_wR9:
317    reg_info.name = "wR9";
318    break;
319  case dwarf_wR10:
320    reg_info.name = "wR10";
321    break;
322  case dwarf_wR11:
323    reg_info.name = "wR11";
324    break;
325  case dwarf_wR12:
326    reg_info.name = "wR12";
327    break;
328  case dwarf_wR13:
329    reg_info.name = "wR13";
330    break;
331  case dwarf_wR14:
332    reg_info.name = "wR14";
333    break;
334  case dwarf_wR15:
335    reg_info.name = "wR15";
336    break;
337
338  case dwarf_spsr:
339    reg_info.name = "spsr";
340    break;
341  case dwarf_spsr_fiq:
342    reg_info.name = "spsr_fiq";
343    break;
344  case dwarf_spsr_irq:
345    reg_info.name = "spsr_irq";
346    break;
347  case dwarf_spsr_abt:
348    reg_info.name = "spsr_abt";
349    break;
350  case dwarf_spsr_und:
351    reg_info.name = "spsr_und";
352    break;
353  case dwarf_spsr_svc:
354    reg_info.name = "spsr_svc";
355    break;
356
357  case dwarf_r8_usr:
358    reg_info.name = "r8_usr";
359    break;
360  case dwarf_r9_usr:
361    reg_info.name = "r9_usr";
362    break;
363  case dwarf_r10_usr:
364    reg_info.name = "r10_usr";
365    break;
366  case dwarf_r11_usr:
367    reg_info.name = "r11_usr";
368    break;
369  case dwarf_r12_usr:
370    reg_info.name = "r12_usr";
371    break;
372  case dwarf_r13_usr:
373    reg_info.name = "r13_usr";
374    break;
375  case dwarf_r14_usr:
376    reg_info.name = "r14_usr";
377    break;
378  case dwarf_r8_fiq:
379    reg_info.name = "r8_fiq";
380    break;
381  case dwarf_r9_fiq:
382    reg_info.name = "r9_fiq";
383    break;
384  case dwarf_r10_fiq:
385    reg_info.name = "r10_fiq";
386    break;
387  case dwarf_r11_fiq:
388    reg_info.name = "r11_fiq";
389    break;
390  case dwarf_r12_fiq:
391    reg_info.name = "r12_fiq";
392    break;
393  case dwarf_r13_fiq:
394    reg_info.name = "r13_fiq";
395    break;
396  case dwarf_r14_fiq:
397    reg_info.name = "r14_fiq";
398    break;
399  case dwarf_r13_irq:
400    reg_info.name = "r13_irq";
401    break;
402  case dwarf_r14_irq:
403    reg_info.name = "r14_irq";
404    break;
405  case dwarf_r13_abt:
406    reg_info.name = "r13_abt";
407    break;
408  case dwarf_r14_abt:
409    reg_info.name = "r14_abt";
410    break;
411  case dwarf_r13_und:
412    reg_info.name = "r13_und";
413    break;
414  case dwarf_r14_und:
415    reg_info.name = "r14_und";
416    break;
417  case dwarf_r13_svc:
418    reg_info.name = "r13_svc";
419    break;
420  case dwarf_r14_svc:
421    reg_info.name = "r14_svc";
422    break;
423
424  // Intel wireless MMX control register in co-processor 0 - 7
425  case dwarf_wC0:
426    reg_info.name = "wC0";
427    break;
428  case dwarf_wC1:
429    reg_info.name = "wC1";
430    break;
431  case dwarf_wC2:
432    reg_info.name = "wC2";
433    break;
434  case dwarf_wC3:
435    reg_info.name = "wC3";
436    break;
437  case dwarf_wC4:
438    reg_info.name = "wC4";
439    break;
440  case dwarf_wC5:
441    reg_info.name = "wC5";
442    break;
443  case dwarf_wC6:
444    reg_info.name = "wC6";
445    break;
446  case dwarf_wC7:
447    reg_info.name = "wC7";
448    break;
449
450  // VFP-v3/Neon
451  case dwarf_d0:
452    reg_info.name = "d0";
453    break;
454  case dwarf_d1:
455    reg_info.name = "d1";
456    break;
457  case dwarf_d2:
458    reg_info.name = "d2";
459    break;
460  case dwarf_d3:
461    reg_info.name = "d3";
462    break;
463  case dwarf_d4:
464    reg_info.name = "d4";
465    break;
466  case dwarf_d5:
467    reg_info.name = "d5";
468    break;
469  case dwarf_d6:
470    reg_info.name = "d6";
471    break;
472  case dwarf_d7:
473    reg_info.name = "d7";
474    break;
475  case dwarf_d8:
476    reg_info.name = "d8";
477    break;
478  case dwarf_d9:
479    reg_info.name = "d9";
480    break;
481  case dwarf_d10:
482    reg_info.name = "d10";
483    break;
484  case dwarf_d11:
485    reg_info.name = "d11";
486    break;
487  case dwarf_d12:
488    reg_info.name = "d12";
489    break;
490  case dwarf_d13:
491    reg_info.name = "d13";
492    break;
493  case dwarf_d14:
494    reg_info.name = "d14";
495    break;
496  case dwarf_d15:
497    reg_info.name = "d15";
498    break;
499  case dwarf_d16:
500    reg_info.name = "d16";
501    break;
502  case dwarf_d17:
503    reg_info.name = "d17";
504    break;
505  case dwarf_d18:
506    reg_info.name = "d18";
507    break;
508  case dwarf_d19:
509    reg_info.name = "d19";
510    break;
511  case dwarf_d20:
512    reg_info.name = "d20";
513    break;
514  case dwarf_d21:
515    reg_info.name = "d21";
516    break;
517  case dwarf_d22:
518    reg_info.name = "d22";
519    break;
520  case dwarf_d23:
521    reg_info.name = "d23";
522    break;
523  case dwarf_d24:
524    reg_info.name = "d24";
525    break;
526  case dwarf_d25:
527    reg_info.name = "d25";
528    break;
529  case dwarf_d26:
530    reg_info.name = "d26";
531    break;
532  case dwarf_d27:
533    reg_info.name = "d27";
534    break;
535  case dwarf_d28:
536    reg_info.name = "d28";
537    break;
538  case dwarf_d29:
539    reg_info.name = "d29";
540    break;
541  case dwarf_d30:
542    reg_info.name = "d30";
543    break;
544  case dwarf_d31:
545    reg_info.name = "d31";
546    break;
547
548  // NEON 128-bit vector registers (overlays the d registers)
549  case dwarf_q0:
550    reg_info.name = "q0";
551    break;
552  case dwarf_q1:
553    reg_info.name = "q1";
554    break;
555  case dwarf_q2:
556    reg_info.name = "q2";
557    break;
558  case dwarf_q3:
559    reg_info.name = "q3";
560    break;
561  case dwarf_q4:
562    reg_info.name = "q4";
563    break;
564  case dwarf_q5:
565    reg_info.name = "q5";
566    break;
567  case dwarf_q6:
568    reg_info.name = "q6";
569    break;
570  case dwarf_q7:
571    reg_info.name = "q7";
572    break;
573  case dwarf_q8:
574    reg_info.name = "q8";
575    break;
576  case dwarf_q9:
577    reg_info.name = "q9";
578    break;
579  case dwarf_q10:
580    reg_info.name = "q10";
581    break;
582  case dwarf_q11:
583    reg_info.name = "q11";
584    break;
585  case dwarf_q12:
586    reg_info.name = "q12";
587    break;
588  case dwarf_q13:
589    reg_info.name = "q13";
590    break;
591  case dwarf_q14:
592    reg_info.name = "q14";
593    break;
594  case dwarf_q15:
595    reg_info.name = "q15";
596    break;
597
598  default:
599    return false;
600  }
601  return true;
602}
603
604// A8.6.50
605// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
606static uint32_t CountITSize(uint32_t ITMask) {
607  // First count the trailing zeros of the IT mask.
608  uint32_t TZ = llvm::countTrailingZeros(ITMask);
609  if (TZ > 3) {
610#ifdef LLDB_CONFIGURATION_DEBUG
611    printf("Encoding error: IT Mask '0000'\n");
612#endif
613    return 0;
614  }
615  return (4 - TZ);
616}
617
618// Init ITState.  Note that at least one bit is always 1 in mask.
619bool ITSession::InitIT(uint32_t bits7_0) {
620  ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
621  if (ITCounter == 0)
622    return false;
623
624  // A8.6.50 IT
625  unsigned short FirstCond = Bits32(bits7_0, 7, 4);
626  if (FirstCond == 0xF) {
627#ifdef LLDB_CONFIGURATION_DEBUG
628    printf("Encoding error: IT FirstCond '1111'\n");
629#endif
630    return false;
631  }
632  if (FirstCond == 0xE && ITCounter != 1) {
633#ifdef LLDB_CONFIGURATION_DEBUG
634    printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
635#endif
636    return false;
637  }
638
639  ITState = bits7_0;
640  return true;
641}
642
643// Update ITState if necessary.
644void ITSession::ITAdvance() {
645  // assert(ITCounter);
646  --ITCounter;
647  if (ITCounter == 0)
648    ITState = 0;
649  else {
650    unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
651    SetBits32(ITState, 4, 0, NewITState4_0);
652  }
653}
654
655// Return true if we're inside an IT Block.
656bool ITSession::InITBlock() { return ITCounter != 0; }
657
658// Return true if we're the last instruction inside an IT Block.
659bool ITSession::LastInITBlock() { return ITCounter == 1; }
660
661// Get condition bits for the current thumb instruction.
662uint32_t ITSession::GetCond() {
663  if (InITBlock())
664    return Bits32(ITState, 7, 4);
665  else
666    return COND_AL;
667}
668
669// ARM constants used during decoding
670#define REG_RD 0
671#define LDM_REGLIST 1
672#define SP_REG 13
673#define LR_REG 14
674#define PC_REG 15
675#define PC_REGLIST_BIT 0x8000
676
677#define ARMv4 (1u << 0)
678#define ARMv4T (1u << 1)
679#define ARMv5T (1u << 2)
680#define ARMv5TE (1u << 3)
681#define ARMv5TEJ (1u << 4)
682#define ARMv6 (1u << 5)
683#define ARMv6K (1u << 6)
684#define ARMv6T2 (1u << 7)
685#define ARMv7 (1u << 8)
686#define ARMv7S (1u << 9)
687#define ARMv8 (1u << 10)
688#define ARMvAll (0xffffffffu)
689
690#define ARMV4T_ABOVE                                                           \
691  (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 |   \
692   ARMv7S | ARMv8)
693#define ARMV5_ABOVE                                                            \
694  (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S |   \
695   ARMv8)
696#define ARMV5TE_ABOVE                                                          \
697  (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
698#define ARMV5J_ABOVE                                                           \
699  (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
700#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
701#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
702#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
703
704#define No_VFP 0
705#define VFPv1 (1u << 1)
706#define VFPv2 (1u << 2)
707#define VFPv3 (1u << 3)
708#define AdvancedSIMD (1u << 4)
709
710#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
711#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
712#define VFPv2v3 (VFPv2 | VFPv3)
713
714//----------------------------------------------------------------------
715//
716// EmulateInstructionARM implementation
717//
718//----------------------------------------------------------------------
719
720void EmulateInstructionARM::Initialize() {
721  PluginManager::RegisterPlugin(GetPluginNameStatic(),
722                                GetPluginDescriptionStatic(), CreateInstance);
723}
724
725void EmulateInstructionARM::Terminate() {
726  PluginManager::UnregisterPlugin(CreateInstance);
727}
728
729ConstString EmulateInstructionARM::GetPluginNameStatic() {
730  static ConstString g_name("arm");
731  return g_name;
732}
733
734const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
735  return "Emulate instructions for the ARM architecture.";
736}
737
738EmulateInstruction *
739EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
740                                      InstructionType inst_type) {
741  if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
742          inst_type)) {
743    if (arch.GetTriple().getArch() == llvm::Triple::arm) {
744      std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
745          new EmulateInstructionARM(arch));
746
747      if (emulate_insn_ap.get())
748        return emulate_insn_ap.release();
749    } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
750      std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
751          new EmulateInstructionARM(arch));
752
753      if (emulate_insn_ap.get())
754        return emulate_insn_ap.release();
755    }
756  }
757
758  return NULL;
759}
760
761bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
762  if (arch.GetTriple().getArch() == llvm::Triple::arm)
763    return true;
764  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
765    return true;
766
767  return false;
768}
769
770// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for
771// many ARM instructions.
772bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
773  EmulateInstruction::Context context;
774  context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
775  context.SetNoArgs();
776
777  uint32_t random_data = rand();
778  const uint32_t addr_byte_size = GetAddressByteSize();
779
780  if (!MemAWrite(context, address, random_data, addr_byte_size))
781    return false;
782
783  return true;
784}
785
786// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM
787// instructions.
788bool EmulateInstructionARM::WriteBits32Unknown(int n) {
789  EmulateInstruction::Context context;
790  context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
791  context.SetNoArgs();
792
793  bool success;
794  uint32_t data =
795      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
796
797  if (!success)
798    return false;
799
800  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
801    return false;
802
803  return true;
804}
805
806bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
807                                            uint32_t reg_num,
808                                            RegisterInfo &reg_info) {
809  if (reg_kind == eRegisterKindGeneric) {
810    switch (reg_num) {
811    case LLDB_REGNUM_GENERIC_PC:
812      reg_kind = eRegisterKindDWARF;
813      reg_num = dwarf_pc;
814      break;
815    case LLDB_REGNUM_GENERIC_SP:
816      reg_kind = eRegisterKindDWARF;
817      reg_num = dwarf_sp;
818      break;
819    case LLDB_REGNUM_GENERIC_FP:
820      reg_kind = eRegisterKindDWARF;
821      reg_num = dwarf_r7;
822      break;
823    case LLDB_REGNUM_GENERIC_RA:
824      reg_kind = eRegisterKindDWARF;
825      reg_num = dwarf_lr;
826      break;
827    case LLDB_REGNUM_GENERIC_FLAGS:
828      reg_kind = eRegisterKindDWARF;
829      reg_num = dwarf_cpsr;
830      break;
831    default:
832      return false;
833    }
834  }
835
836  if (reg_kind == eRegisterKindDWARF)
837    return GetARMDWARFRegisterInfo(reg_num, reg_info);
838  return false;
839}
840
841uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
842  if (m_arch.GetTriple().isAndroid())
843    return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
844  bool is_apple = false;
845  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
846    is_apple = true;
847  switch (m_arch.GetTriple().getOS()) {
848  case llvm::Triple::Darwin:
849  case llvm::Triple::MacOSX:
850  case llvm::Triple::IOS:
851  case llvm::Triple::TvOS:
852  case llvm::Triple::WatchOS:
853    is_apple = true;
854    break;
855  default:
856    break;
857  }
858
859  /* On Apple iOS et al, the frame pointer register is always r7.
860   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
861   */
862
863  uint32_t fp_regnum = 11;
864
865  if (is_apple)
866    fp_regnum = 7;
867
868  if (m_opcode_mode == eModeThumb)
869    fp_regnum = 7;
870
871  return fp_regnum;
872}
873
874uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
875  bool is_apple = false;
876  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
877    is_apple = true;
878  switch (m_arch.GetTriple().getOS()) {
879  case llvm::Triple::Darwin:
880  case llvm::Triple::MacOSX:
881  case llvm::Triple::IOS:
882    is_apple = true;
883    break;
884  default:
885    break;
886  }
887
888  /* On Apple iOS et al, the frame pointer register is always r7.
889   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
890   */
891
892  uint32_t fp_regnum = dwarf_r11;
893
894  if (is_apple)
895    fp_regnum = dwarf_r7;
896
897  if (m_opcode_mode == eModeThumb)
898    fp_regnum = dwarf_r7;
899
900  return fp_regnum;
901}
902
903// Push Multiple Registers stores multiple registers to the stack, storing to
904// consecutive memory locations ending just below the address in SP, and updates
905// SP to point to the start of the stored data.
906bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
907                                        const ARMEncoding encoding) {
908#if 0
909    // ARM pseudo code...
910    if (ConditionPassed())
911    {
912        EncodingSpecificOperations();
913        NullCheckIfThumbEE(13);
914        address = SP - 4*BitCount(registers);
915
916        for (i = 0 to 14)
917        {
918            if (registers<i> == '1')
919            {
920                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
921                    MemA[address,4] = bits(32) UNKNOWN;
922                else
923                    MemA[address,4] = R[i];
924                address = address + 4;
925            }
926        }
927
928        if (registers<15> == '1') // Only possible for encoding A1 or A2
929            MemA[address,4] = PCStoreValue();
930
931        SP = SP - 4*BitCount(registers);
932    }
933#endif
934
935  bool success = false;
936  if (ConditionPassed(opcode)) {
937    const uint32_t addr_byte_size = GetAddressByteSize();
938    const addr_t sp = ReadCoreReg(SP_REG, &success);
939    if (!success)
940      return false;
941    uint32_t registers = 0;
942    uint32_t Rt; // the source register
943    switch (encoding) {
944    case eEncodingT1:
945      registers = Bits32(opcode, 7, 0);
946      // The M bit represents LR.
947      if (Bit32(opcode, 8))
948        registers |= (1u << 14);
949      // if BitCount(registers) < 1 then UNPREDICTABLE;
950      if (BitCount(registers) < 1)
951        return false;
952      break;
953    case eEncodingT2:
954      // Ignore bits 15 & 13.
955      registers = Bits32(opcode, 15, 0) & ~0xa000;
956      // if BitCount(registers) < 2 then UNPREDICTABLE;
957      if (BitCount(registers) < 2)
958        return false;
959      break;
960    case eEncodingT3:
961      Rt = Bits32(opcode, 15, 12);
962      // if BadReg(t) then UNPREDICTABLE;
963      if (BadReg(Rt))
964        return false;
965      registers = (1u << Rt);
966      break;
967    case eEncodingA1:
968      registers = Bits32(opcode, 15, 0);
969      // Instead of return false, let's handle the following case as well,
970      // which amounts to pushing one reg onto the full descending stacks.
971      // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
972      break;
973    case eEncodingA2:
974      Rt = Bits32(opcode, 15, 12);
975      // if t == 13 then UNPREDICTABLE;
976      if (Rt == dwarf_sp)
977        return false;
978      registers = (1u << Rt);
979      break;
980    default:
981      return false;
982    }
983    addr_t sp_offset = addr_byte_size * BitCount(registers);
984    addr_t addr = sp - sp_offset;
985    uint32_t i;
986
987    EmulateInstruction::Context context;
988    context.type = EmulateInstruction::eContextPushRegisterOnStack;
989    RegisterInfo reg_info;
990    RegisterInfo sp_reg;
991    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
992    for (i = 0; i < 15; ++i) {
993      if (BitIsSet(registers, i)) {
994        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
995        context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
996        uint32_t reg_value = ReadCoreReg(i, &success);
997        if (!success)
998          return false;
999        if (!MemAWrite(context, addr, reg_value, addr_byte_size))
1000          return false;
1001        addr += addr_byte_size;
1002      }
1003    }
1004
1005    if (BitIsSet(registers, 15)) {
1006      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
1007      context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
1008      const uint32_t pc = ReadCoreReg(PC_REG, &success);
1009      if (!success)
1010        return false;
1011      if (!MemAWrite(context, addr, pc, addr_byte_size))
1012        return false;
1013    }
1014
1015    context.type = EmulateInstruction::eContextAdjustStackPointer;
1016    context.SetImmediateSigned(-sp_offset);
1017
1018    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1019                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1020      return false;
1021  }
1022  return true;
1023}
1024
1025// Pop Multiple Registers loads multiple registers from the stack, loading from
1026// consecutive memory locations staring at the address in SP, and updates
1027// SP to point just above the loaded data.
1028bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1029                                       const ARMEncoding encoding) {
1030#if 0
1031    // ARM pseudo code...
1032    if (ConditionPassed())
1033    {
1034        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1035        address = SP;
1036        for i = 0 to 14
1037            if registers<i> == '1' then
1038                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1039        if registers<15> == '1' then
1040            if UnalignedAllowed then
1041                LoadWritePC(MemU[address,4]);
1042            else
1043                LoadWritePC(MemA[address,4]);
1044        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1045        if registers<13> == '1' then SP = bits(32) UNKNOWN;
1046    }
1047#endif
1048
1049  bool success = false;
1050
1051  if (ConditionPassed(opcode)) {
1052    const uint32_t addr_byte_size = GetAddressByteSize();
1053    const addr_t sp = ReadCoreReg(SP_REG, &success);
1054    if (!success)
1055      return false;
1056    uint32_t registers = 0;
1057    uint32_t Rt; // the destination register
1058    switch (encoding) {
1059    case eEncodingT1:
1060      registers = Bits32(opcode, 7, 0);
1061      // The P bit represents PC.
1062      if (Bit32(opcode, 8))
1063        registers |= (1u << 15);
1064      // if BitCount(registers) < 1 then UNPREDICTABLE;
1065      if (BitCount(registers) < 1)
1066        return false;
1067      break;
1068    case eEncodingT2:
1069      // Ignore bit 13.
1070      registers = Bits32(opcode, 15, 0) & ~0x2000;
1071      // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1072      // UNPREDICTABLE;
1073      if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1074        return false;
1075      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1076      // UNPREDICTABLE;
1077      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1078        return false;
1079      break;
1080    case eEncodingT3:
1081      Rt = Bits32(opcode, 15, 12);
1082      // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1083      // UNPREDICTABLE;
1084      if (Rt == 13)
1085        return false;
1086      if (Rt == 15 && InITBlock() && !LastInITBlock())
1087        return false;
1088      registers = (1u << Rt);
1089      break;
1090    case eEncodingA1:
1091      registers = Bits32(opcode, 15, 0);
1092      // Instead of return false, let's handle the following case as well,
1093      // which amounts to popping one reg from the full descending stacks.
1094      // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1095
1096      // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1097      if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1098        return false;
1099      break;
1100    case eEncodingA2:
1101      Rt = Bits32(opcode, 15, 12);
1102      // if t == 13 then UNPREDICTABLE;
1103      if (Rt == dwarf_sp)
1104        return false;
1105      registers = (1u << Rt);
1106      break;
1107    default:
1108      return false;
1109    }
1110    addr_t sp_offset = addr_byte_size * BitCount(registers);
1111    addr_t addr = sp;
1112    uint32_t i, data;
1113
1114    EmulateInstruction::Context context;
1115    context.type = EmulateInstruction::eContextPopRegisterOffStack;
1116
1117    RegisterInfo sp_reg;
1118    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1119
1120    for (i = 0; i < 15; ++i) {
1121      if (BitIsSet(registers, i)) {
1122        context.SetAddress(addr);
1123        data = MemARead(context, addr, 4, 0, &success);
1124        if (!success)
1125          return false;
1126        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1127                                   data))
1128          return false;
1129        addr += addr_byte_size;
1130      }
1131    }
1132
1133    if (BitIsSet(registers, 15)) {
1134      context.SetRegisterPlusOffset(sp_reg, addr - sp);
1135      data = MemARead(context, addr, 4, 0, &success);
1136      if (!success)
1137        return false;
1138      // In ARMv5T and above, this is an interworking branch.
1139      if (!LoadWritePC(context, data))
1140        return false;
1141      // addr += addr_byte_size;
1142    }
1143
1144    context.type = EmulateInstruction::eContextAdjustStackPointer;
1145    context.SetImmediateSigned(sp_offset);
1146
1147    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1148                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1149      return false;
1150  }
1151  return true;
1152}
1153
1154// Set r7 or ip to point to saved value residing within the stack.
1155// ADD (SP plus immediate)
1156bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1157                                              const ARMEncoding encoding) {
1158#if 0
1159    // ARM pseudo code...
1160    if (ConditionPassed())
1161    {
1162        EncodingSpecificOperations();
1163        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1164        if d == 15 then
1165           ALUWritePC(result); // setflags is always FALSE here
1166        else
1167            R[d] = result;
1168            if setflags then
1169                APSR.N = result<31>;
1170                APSR.Z = IsZeroBit(result);
1171                APSR.C = carry;
1172                APSR.V = overflow;
1173    }
1174#endif
1175
1176  bool success = false;
1177
1178  if (ConditionPassed(opcode)) {
1179    const addr_t sp = ReadCoreReg(SP_REG, &success);
1180    if (!success)
1181      return false;
1182    uint32_t Rd; // the destination register
1183    uint32_t imm32;
1184    switch (encoding) {
1185    case eEncodingT1:
1186      Rd = 7;
1187      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1188      break;
1189    case eEncodingA1:
1190      Rd = Bits32(opcode, 15, 12);
1191      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1192      break;
1193    default:
1194      return false;
1195    }
1196    addr_t sp_offset = imm32;
1197    addr_t addr = sp + sp_offset; // a pointer to the stack area
1198
1199    EmulateInstruction::Context context;
1200    if (Rd == GetFramePointerRegisterNumber())
1201      context.type = eContextSetFramePointer;
1202    else
1203      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1204    RegisterInfo sp_reg;
1205    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1206    context.SetRegisterPlusOffset(sp_reg, sp_offset);
1207
1208    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1209                               addr))
1210      return false;
1211  }
1212  return true;
1213}
1214
1215// Set r7 or ip to the current stack pointer.
1216// MOV (register)
1217bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1218                                           const ARMEncoding encoding) {
1219#if 0
1220    // ARM pseudo code...
1221    if (ConditionPassed())
1222    {
1223        EncodingSpecificOperations();
1224        result = R[m];
1225        if d == 15 then
1226            ALUWritePC(result); // setflags is always FALSE here
1227        else
1228            R[d] = result;
1229            if setflags then
1230                APSR.N = result<31>;
1231                APSR.Z = IsZeroBit(result);
1232                // APSR.C unchanged
1233                // APSR.V unchanged
1234    }
1235#endif
1236
1237  bool success = false;
1238
1239  if (ConditionPassed(opcode)) {
1240    const addr_t sp = ReadCoreReg(SP_REG, &success);
1241    if (!success)
1242      return false;
1243    uint32_t Rd; // the destination register
1244    switch (encoding) {
1245    case eEncodingT1:
1246      Rd = 7;
1247      break;
1248    case eEncodingA1:
1249      Rd = 12;
1250      break;
1251    default:
1252      return false;
1253    }
1254
1255    EmulateInstruction::Context context;
1256    if (Rd == GetFramePointerRegisterNumber())
1257      context.type = EmulateInstruction::eContextSetFramePointer;
1258    else
1259      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1260    RegisterInfo sp_reg;
1261    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1262    context.SetRegisterPlusOffset(sp_reg, 0);
1263
1264    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1265      return false;
1266  }
1267  return true;
1268}
1269
1270// Move from high register (r8-r15) to low register (r0-r7).
1271// MOV (register)
1272bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1273                                              const ARMEncoding encoding) {
1274  return EmulateMOVRdRm(opcode, encoding);
1275}
1276
1277// Move from register to register.
1278// MOV (register)
1279bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1280                                           const ARMEncoding encoding) {
1281#if 0
1282    // ARM pseudo code...
1283    if (ConditionPassed())
1284    {
1285        EncodingSpecificOperations();
1286        result = R[m];
1287        if d == 15 then
1288            ALUWritePC(result); // setflags is always FALSE here
1289        else
1290            R[d] = result;
1291            if setflags then
1292                APSR.N = result<31>;
1293                APSR.Z = IsZeroBit(result);
1294                // APSR.C unchanged
1295                // APSR.V unchanged
1296    }
1297#endif
1298
1299  bool success = false;
1300
1301  if (ConditionPassed(opcode)) {
1302    uint32_t Rm; // the source register
1303    uint32_t Rd; // the destination register
1304    bool setflags;
1305    switch (encoding) {
1306    case eEncodingT1:
1307      Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1308      Rm = Bits32(opcode, 6, 3);
1309      setflags = false;
1310      if (Rd == 15 && InITBlock() && !LastInITBlock())
1311        return false;
1312      break;
1313    case eEncodingT2:
1314      Rd = Bits32(opcode, 2, 0);
1315      Rm = Bits32(opcode, 5, 3);
1316      setflags = true;
1317      if (InITBlock())
1318        return false;
1319      break;
1320    case eEncodingT3:
1321      Rd = Bits32(opcode, 11, 8);
1322      Rm = Bits32(opcode, 3, 0);
1323      setflags = BitIsSet(opcode, 20);
1324      // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1325      if (setflags && (BadReg(Rd) || BadReg(Rm)))
1326        return false;
1327      // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1328      // UNPREDICTABLE;
1329      if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1330        return false;
1331      break;
1332    case eEncodingA1:
1333      Rd = Bits32(opcode, 15, 12);
1334      Rm = Bits32(opcode, 3, 0);
1335      setflags = BitIsSet(opcode, 20);
1336
1337      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1338      // instructions;
1339      if (Rd == 15 && setflags)
1340        return EmulateSUBSPcLrEtc(opcode, encoding);
1341      break;
1342    default:
1343      return false;
1344    }
1345    uint32_t result = ReadCoreReg(Rm, &success);
1346    if (!success)
1347      return false;
1348
1349    // The context specifies that Rm is to be moved into Rd.
1350    EmulateInstruction::Context context;
1351    if (Rd == 13)
1352      context.type = EmulateInstruction::eContextAdjustStackPointer;
1353    else
1354      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1355    RegisterInfo dwarf_reg;
1356    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1357    context.SetRegisterPlusOffset(dwarf_reg, 0);
1358
1359    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1360      return false;
1361  }
1362  return true;
1363}
1364
1365// Move (immediate) writes an immediate value to the destination register.  It
1366// can optionally update the condition flags based on the value.
1367// MOV (immediate)
1368bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1369                                            const ARMEncoding encoding) {
1370#if 0
1371    // ARM pseudo code...
1372    if (ConditionPassed())
1373    {
1374        EncodingSpecificOperations();
1375        result = imm32;
1376        if d == 15 then         // Can only occur for ARM encoding
1377            ALUWritePC(result); // setflags is always FALSE here
1378        else
1379            R[d] = result;
1380            if setflags then
1381                APSR.N = result<31>;
1382                APSR.Z = IsZeroBit(result);
1383                APSR.C = carry;
1384                // APSR.V unchanged
1385    }
1386#endif
1387
1388  if (ConditionPassed(opcode)) {
1389    uint32_t Rd;    // the destination register
1390    uint32_t imm32; // the immediate value to be written to Rd
1391    uint32_t carry =
1392        0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1393           // for setflags == false, this value is a don't care
1394           // initialized to 0 to silence the static analyzer
1395    bool setflags;
1396    switch (encoding) {
1397    case eEncodingT1:
1398      Rd = Bits32(opcode, 10, 8);
1399      setflags = !InITBlock();
1400      imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1401      carry = APSR_C;
1402
1403      break;
1404
1405    case eEncodingT2:
1406      Rd = Bits32(opcode, 11, 8);
1407      setflags = BitIsSet(opcode, 20);
1408      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1409      if (BadReg(Rd))
1410        return false;
1411
1412      break;
1413
1414    case eEncodingT3: {
1415      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1416      // 32);
1417      Rd = Bits32(opcode, 11, 8);
1418      setflags = false;
1419      uint32_t imm4 = Bits32(opcode, 19, 16);
1420      uint32_t imm3 = Bits32(opcode, 14, 12);
1421      uint32_t i = Bit32(opcode, 26);
1422      uint32_t imm8 = Bits32(opcode, 7, 0);
1423      imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1424
1425      // if BadReg(d) then UNPREDICTABLE;
1426      if (BadReg(Rd))
1427        return false;
1428    } break;
1429
1430    case eEncodingA1:
1431      // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1432      // ARMExpandImm_C(imm12, APSR.C);
1433      Rd = Bits32(opcode, 15, 12);
1434      setflags = BitIsSet(opcode, 20);
1435      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1436
1437      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1438      // instructions;
1439      if ((Rd == 15) && setflags)
1440        return EmulateSUBSPcLrEtc(opcode, encoding);
1441
1442      break;
1443
1444    case eEncodingA2: {
1445      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1446      Rd = Bits32(opcode, 15, 12);
1447      setflags = false;
1448      uint32_t imm4 = Bits32(opcode, 19, 16);
1449      uint32_t imm12 = Bits32(opcode, 11, 0);
1450      imm32 = (imm4 << 12) | imm12;
1451
1452      // if d == 15 then UNPREDICTABLE;
1453      if (Rd == 15)
1454        return false;
1455    } break;
1456
1457    default:
1458      return false;
1459    }
1460    uint32_t result = imm32;
1461
1462    // The context specifies that an immediate is to be moved into Rd.
1463    EmulateInstruction::Context context;
1464    context.type = EmulateInstruction::eContextImmediate;
1465    context.SetNoArgs();
1466
1467    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1468      return false;
1469  }
1470  return true;
1471}
1472
1473// MUL multiplies two register values.  The least significant 32 bits of the
1474// result are written to the destination
1475// register.  These 32 bits do not depend on whether the source register values
1476// are considered to be signed values or
1477// unsigned values.
1478//
1479// Optionally, it can update the condition flags based on the result.  In the
1480// Thumb instruction set, this option is
1481// limited to only a few forms of the instruction.
1482bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1483                                       const ARMEncoding encoding) {
1484#if 0
1485    if ConditionPassed() then
1486        EncodingSpecificOperations();
1487        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1488        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1489        result = operand1 * operand2;
1490        R[d] = result<31:0>;
1491        if setflags then
1492            APSR.N = result<31>;
1493            APSR.Z = IsZeroBit(result);
1494            if ArchVersion() == 4 then
1495                APSR.C = bit UNKNOWN;
1496            // else APSR.C unchanged
1497            // APSR.V always unchanged
1498#endif
1499
1500  if (ConditionPassed(opcode)) {
1501    uint32_t d;
1502    uint32_t n;
1503    uint32_t m;
1504    bool setflags;
1505
1506    // EncodingSpecificOperations();
1507    switch (encoding) {
1508    case eEncodingT1:
1509      // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1510      d = Bits32(opcode, 2, 0);
1511      n = Bits32(opcode, 5, 3);
1512      m = Bits32(opcode, 2, 0);
1513      setflags = !InITBlock();
1514
1515      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1516      if ((ArchVersion() < ARMv6) && (d == n))
1517        return false;
1518
1519      break;
1520
1521    case eEncodingT2:
1522      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1523      d = Bits32(opcode, 11, 8);
1524      n = Bits32(opcode, 19, 16);
1525      m = Bits32(opcode, 3, 0);
1526      setflags = false;
1527
1528      // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1529      if (BadReg(d) || BadReg(n) || BadReg(m))
1530        return false;
1531
1532      break;
1533
1534    case eEncodingA1:
1535      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1536      d = Bits32(opcode, 19, 16);
1537      n = Bits32(opcode, 3, 0);
1538      m = Bits32(opcode, 11, 8);
1539      setflags = BitIsSet(opcode, 20);
1540
1541      // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1542      if ((d == 15) || (n == 15) || (m == 15))
1543        return false;
1544
1545      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1546      if ((ArchVersion() < ARMv6) && (d == n))
1547        return false;
1548
1549      break;
1550
1551    default:
1552      return false;
1553    }
1554
1555    bool success = false;
1556
1557    // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1558    // results
1559    uint64_t operand1 =
1560        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1561    if (!success)
1562      return false;
1563
1564    // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1565    // results
1566    uint64_t operand2 =
1567        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1568    if (!success)
1569      return false;
1570
1571    // result = operand1 * operand2;
1572    uint64_t result = operand1 * operand2;
1573
1574    // R[d] = result<31:0>;
1575    RegisterInfo op1_reg;
1576    RegisterInfo op2_reg;
1577    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1578    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1579
1580    EmulateInstruction::Context context;
1581    context.type = eContextArithmetic;
1582    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1583
1584    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1585                               (0x0000ffff & result)))
1586      return false;
1587
1588    // if setflags then
1589    if (setflags) {
1590      // APSR.N = result<31>;
1591      // APSR.Z = IsZeroBit(result);
1592      m_new_inst_cpsr = m_opcode_cpsr;
1593      SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1594      SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1595      if (m_new_inst_cpsr != m_opcode_cpsr) {
1596        if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1597                                   LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1598          return false;
1599      }
1600
1601      // if ArchVersion() == 4 then
1602      // APSR.C = bit UNKNOWN;
1603    }
1604  }
1605  return true;
1606}
1607
1608// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1609// the destination register.
1610// It can optionally update the condition flags based on the value.
1611bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1612                                          const ARMEncoding encoding) {
1613#if 0
1614    // ARM pseudo code...
1615    if (ConditionPassed())
1616    {
1617        EncodingSpecificOperations();
1618        result = NOT(imm32);
1619        if d == 15 then         // Can only occur for ARM encoding
1620            ALUWritePC(result); // setflags is always FALSE here
1621        else
1622            R[d] = result;
1623            if setflags then
1624                APSR.N = result<31>;
1625                APSR.Z = IsZeroBit(result);
1626                APSR.C = carry;
1627                // APSR.V unchanged
1628    }
1629#endif
1630
1631  if (ConditionPassed(opcode)) {
1632    uint32_t Rd;    // the destination register
1633    uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1634    uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1635    bool setflags;
1636    switch (encoding) {
1637    case eEncodingT1:
1638      Rd = Bits32(opcode, 11, 8);
1639      setflags = BitIsSet(opcode, 20);
1640      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1641      break;
1642    case eEncodingA1:
1643      Rd = Bits32(opcode, 15, 12);
1644      setflags = BitIsSet(opcode, 20);
1645      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1646
1647      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1648      // instructions;
1649      if (Rd == 15 && setflags)
1650        return EmulateSUBSPcLrEtc(opcode, encoding);
1651      break;
1652    default:
1653      return false;
1654    }
1655    uint32_t result = ~imm32;
1656
1657    // The context specifies that an immediate is to be moved into Rd.
1658    EmulateInstruction::Context context;
1659    context.type = EmulateInstruction::eContextImmediate;
1660    context.SetNoArgs();
1661
1662    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1663      return false;
1664  }
1665  return true;
1666}
1667
1668// Bitwise NOT (register) writes the bitwise inverse of a register value to the
1669// destination register.
1670// It can optionally update the condition flags based on the result.
1671bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1672                                          const ARMEncoding encoding) {
1673#if 0
1674    // ARM pseudo code...
1675    if (ConditionPassed())
1676    {
1677        EncodingSpecificOperations();
1678        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1679        result = NOT(shifted);
1680        if d == 15 then         // Can only occur for ARM encoding
1681            ALUWritePC(result); // setflags is always FALSE here
1682        else
1683            R[d] = result;
1684            if setflags then
1685                APSR.N = result<31>;
1686                APSR.Z = IsZeroBit(result);
1687                APSR.C = carry;
1688                // APSR.V unchanged
1689    }
1690#endif
1691
1692  if (ConditionPassed(opcode)) {
1693    uint32_t Rm; // the source register
1694    uint32_t Rd; // the destination register
1695    ARM_ShifterType shift_t;
1696    uint32_t shift_n; // the shift applied to the value read from Rm
1697    bool setflags;
1698    uint32_t carry; // the carry bit after the shift operation
1699    switch (encoding) {
1700    case eEncodingT1:
1701      Rd = Bits32(opcode, 2, 0);
1702      Rm = Bits32(opcode, 5, 3);
1703      setflags = !InITBlock();
1704      shift_t = SRType_LSL;
1705      shift_n = 0;
1706      if (InITBlock())
1707        return false;
1708      break;
1709    case eEncodingT2:
1710      Rd = Bits32(opcode, 11, 8);
1711      Rm = Bits32(opcode, 3, 0);
1712      setflags = BitIsSet(opcode, 20);
1713      shift_n = DecodeImmShiftThumb(opcode, shift_t);
1714      // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1715      if (BadReg(Rd) || BadReg(Rm))
1716        return false;
1717      break;
1718    case eEncodingA1:
1719      Rd = Bits32(opcode, 15, 12);
1720      Rm = Bits32(opcode, 3, 0);
1721      setflags = BitIsSet(opcode, 20);
1722      shift_n = DecodeImmShiftARM(opcode, shift_t);
1723      break;
1724    default:
1725      return false;
1726    }
1727    bool success = false;
1728    uint32_t value = ReadCoreReg(Rm, &success);
1729    if (!success)
1730      return false;
1731
1732    uint32_t shifted =
1733        Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1734    if (!success)
1735      return false;
1736    uint32_t result = ~shifted;
1737
1738    // The context specifies that an immediate is to be moved into Rd.
1739    EmulateInstruction::Context context;
1740    context.type = EmulateInstruction::eContextImmediate;
1741    context.SetNoArgs();
1742
1743    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1744      return false;
1745  }
1746  return true;
1747}
1748
1749// PC relative immediate load into register, possibly followed by ADD (SP plus
1750// register).
1751// LDR (literal)
1752bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1753                                                   const ARMEncoding encoding) {
1754#if 0
1755    // ARM pseudo code...
1756    if (ConditionPassed())
1757    {
1758        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1759        base = Align(PC,4);
1760        address = if add then (base + imm32) else (base - imm32);
1761        data = MemU[address,4];
1762        if t == 15 then
1763            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1764        elsif UnalignedSupport() || address<1:0> = '00' then
1765            R[t] = data;
1766        else // Can only apply before ARMv7
1767            if CurrentInstrSet() == InstrSet_ARM then
1768                R[t] = ROR(data, 8*UInt(address<1:0>));
1769            else
1770                R[t] = bits(32) UNKNOWN;
1771    }
1772#endif
1773
1774  if (ConditionPassed(opcode)) {
1775    bool success = false;
1776    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1777    if (!success)
1778      return false;
1779
1780    // PC relative immediate load context
1781    EmulateInstruction::Context context;
1782    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1783    RegisterInfo pc_reg;
1784    GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1785    context.SetRegisterPlusOffset(pc_reg, 0);
1786
1787    uint32_t Rt;    // the destination register
1788    uint32_t imm32; // immediate offset from the PC
1789    bool add;       // +imm32 or -imm32?
1790    addr_t base;    // the base address
1791    addr_t address; // the PC relative address
1792    uint32_t data;  // the literal data value from the PC relative load
1793    switch (encoding) {
1794    case eEncodingT1:
1795      Rt = Bits32(opcode, 10, 8);
1796      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1797      add = true;
1798      break;
1799    case eEncodingT2:
1800      Rt = Bits32(opcode, 15, 12);
1801      imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1802      add = BitIsSet(opcode, 23);
1803      if (Rt == 15 && InITBlock() && !LastInITBlock())
1804        return false;
1805      break;
1806    default:
1807      return false;
1808    }
1809
1810    base = Align(pc, 4);
1811    if (add)
1812      address = base + imm32;
1813    else
1814      address = base - imm32;
1815
1816    context.SetRegisterPlusOffset(pc_reg, address - base);
1817    data = MemURead(context, address, 4, 0, &success);
1818    if (!success)
1819      return false;
1820
1821    if (Rt == 15) {
1822      if (Bits32(address, 1, 0) == 0) {
1823        // In ARMv5T and above, this is an interworking branch.
1824        if (!LoadWritePC(context, data))
1825          return false;
1826      } else
1827        return false;
1828    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1829      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1830                                 data))
1831        return false;
1832    } else // We don't handle ARM for now.
1833      return false;
1834  }
1835  return true;
1836}
1837
1838// An add operation to adjust the SP.
1839// ADD (SP plus immediate)
1840bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1841                                            const ARMEncoding encoding) {
1842#if 0
1843    // ARM pseudo code...
1844    if (ConditionPassed())
1845    {
1846        EncodingSpecificOperations();
1847        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1848        if d == 15 then // Can only occur for ARM encoding
1849            ALUWritePC(result); // setflags is always FALSE here
1850        else
1851            R[d] = result;
1852            if setflags then
1853                APSR.N = result<31>;
1854                APSR.Z = IsZeroBit(result);
1855                APSR.C = carry;
1856                APSR.V = overflow;
1857    }
1858#endif
1859
1860  bool success = false;
1861
1862  if (ConditionPassed(opcode)) {
1863    const addr_t sp = ReadCoreReg(SP_REG, &success);
1864    if (!success)
1865      return false;
1866    uint32_t imm32; // the immediate operand
1867    uint32_t d;
1868    bool setflags;
1869    switch (encoding) {
1870    case eEncodingT1:
1871      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1872      d = Bits32(opcode, 10, 8);
1873      imm32 = (Bits32(opcode, 7, 0) << 2);
1874      setflags = false;
1875      break;
1876
1877    case eEncodingT2:
1878      // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1879      d = 13;
1880      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1881      setflags = false;
1882      break;
1883
1884    case eEncodingT3:
1885      // d = UInt(Rd); setflags = (S == "1"); imm32 =
1886      // ThumbExpandImm(i:imm3:imm8);
1887      d = Bits32(opcode, 11, 8);
1888      imm32 = ThumbExpandImm(opcode);
1889      setflags = Bit32(opcode, 20);
1890
1891      // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1892      if (d == 15 && setflags == 1)
1893        return false; // CMN (immediate) not yet supported
1894
1895      // if d == 15 && S == "0" then UNPREDICTABLE;
1896      if (d == 15 && setflags == 0)
1897        return false;
1898      break;
1899
1900    case eEncodingT4: {
1901      // if Rn == '1111' then SEE ADR;
1902      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1903      d = Bits32(opcode, 11, 8);
1904      setflags = false;
1905      uint32_t i = Bit32(opcode, 26);
1906      uint32_t imm3 = Bits32(opcode, 14, 12);
1907      uint32_t imm8 = Bits32(opcode, 7, 0);
1908      imm32 = (i << 11) | (imm3 << 8) | imm8;
1909
1910      // if d == 15 then UNPREDICTABLE;
1911      if (d == 15)
1912        return false;
1913    } break;
1914
1915    default:
1916      return false;
1917    }
1918    // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1919    AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1920
1921    EmulateInstruction::Context context;
1922    if (d == 13)
1923      context.type = EmulateInstruction::eContextAdjustStackPointer;
1924    else
1925      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1926
1927    RegisterInfo sp_reg;
1928    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1929    context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1930
1931    if (d == 15) {
1932      if (!ALUWritePC(context, res.result))
1933        return false;
1934    } else {
1935      // R[d] = result;
1936      // if setflags then
1937      //     APSR.N = result<31>;
1938      //     APSR.Z = IsZeroBit(result);
1939      //     APSR.C = carry;
1940      //     APSR.V = overflow;
1941      if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1942                                     res.carry_out, res.overflow))
1943        return false;
1944    }
1945  }
1946  return true;
1947}
1948
1949// An add operation to adjust the SP.
1950// ADD (SP plus register)
1951bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1952                                           const ARMEncoding encoding) {
1953#if 0
1954    // ARM pseudo code...
1955    if (ConditionPassed())
1956    {
1957        EncodingSpecificOperations();
1958        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1959        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1960        if d == 15 then
1961            ALUWritePC(result); // setflags is always FALSE here
1962        else
1963            R[d] = result;
1964            if setflags then
1965                APSR.N = result<31>;
1966                APSR.Z = IsZeroBit(result);
1967                APSR.C = carry;
1968                APSR.V = overflow;
1969    }
1970#endif
1971
1972  bool success = false;
1973
1974  if (ConditionPassed(opcode)) {
1975    const addr_t sp = ReadCoreReg(SP_REG, &success);
1976    if (!success)
1977      return false;
1978    uint32_t Rm; // the second operand
1979    switch (encoding) {
1980    case eEncodingT2:
1981      Rm = Bits32(opcode, 6, 3);
1982      break;
1983    default:
1984      return false;
1985    }
1986    int32_t reg_value = ReadCoreReg(Rm, &success);
1987    if (!success)
1988      return false;
1989
1990    addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1991
1992    EmulateInstruction::Context context;
1993    context.type = eContextArithmetic;
1994    RegisterInfo sp_reg;
1995    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1996
1997    RegisterInfo other_reg;
1998    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1999    context.SetRegisterRegisterOperands(sp_reg, other_reg);
2000
2001    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2002                               LLDB_REGNUM_GENERIC_SP, addr))
2003      return false;
2004  }
2005  return true;
2006}
2007
2008// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
2009// at a PC-relative address, and changes instruction set from ARM to Thumb, or
2010// from Thumb to ARM.
2011// BLX (immediate)
2012bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2013                                                const ARMEncoding encoding) {
2014#if 0
2015    // ARM pseudo code...
2016    if (ConditionPassed())
2017    {
2018        EncodingSpecificOperations();
2019        if CurrentInstrSet() == InstrSet_ARM then
2020            LR = PC - 4;
2021        else
2022            LR = PC<31:1> : '1';
2023        if targetInstrSet == InstrSet_ARM then
2024            targetAddress = Align(PC,4) + imm32;
2025        else
2026            targetAddress = PC + imm32;
2027        SelectInstrSet(targetInstrSet);
2028        BranchWritePC(targetAddress);
2029    }
2030#endif
2031
2032  bool success = true;
2033
2034  if (ConditionPassed(opcode)) {
2035    EmulateInstruction::Context context;
2036    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2037    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2038    if (!success)
2039      return false;
2040    addr_t lr;     // next instruction address
2041    addr_t target; // target address
2042    int32_t imm32; // PC-relative offset
2043    switch (encoding) {
2044    case eEncodingT1: {
2045      lr = pc | 1u; // return address
2046      uint32_t S = Bit32(opcode, 26);
2047      uint32_t imm10 = Bits32(opcode, 25, 16);
2048      uint32_t J1 = Bit32(opcode, 13);
2049      uint32_t J2 = Bit32(opcode, 11);
2050      uint32_t imm11 = Bits32(opcode, 10, 0);
2051      uint32_t I1 = !(J1 ^ S);
2052      uint32_t I2 = !(J2 ^ S);
2053      uint32_t imm25 =
2054          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2055      imm32 = llvm::SignExtend32<25>(imm25);
2056      target = pc + imm32;
2057      SelectInstrSet(eModeThumb);
2058      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2059      if (InITBlock() && !LastInITBlock())
2060        return false;
2061      break;
2062    }
2063    case eEncodingT2: {
2064      lr = pc | 1u; // return address
2065      uint32_t S = Bit32(opcode, 26);
2066      uint32_t imm10H = Bits32(opcode, 25, 16);
2067      uint32_t J1 = Bit32(opcode, 13);
2068      uint32_t J2 = Bit32(opcode, 11);
2069      uint32_t imm10L = Bits32(opcode, 10, 1);
2070      uint32_t I1 = !(J1 ^ S);
2071      uint32_t I2 = !(J2 ^ S);
2072      uint32_t imm25 =
2073          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2074      imm32 = llvm::SignExtend32<25>(imm25);
2075      target = Align(pc, 4) + imm32;
2076      SelectInstrSet(eModeARM);
2077      context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2078      if (InITBlock() && !LastInITBlock())
2079        return false;
2080      break;
2081    }
2082    case eEncodingA1:
2083      lr = pc - 4; // return address
2084      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2085      target = Align(pc, 4) + imm32;
2086      SelectInstrSet(eModeARM);
2087      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2088      break;
2089    case eEncodingA2:
2090      lr = pc - 4; // return address
2091      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2092                                     Bits32(opcode, 24, 24) << 1);
2093      target = pc + imm32;
2094      SelectInstrSet(eModeThumb);
2095      context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2096      break;
2097    default:
2098      return false;
2099    }
2100    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2101                               LLDB_REGNUM_GENERIC_RA, lr))
2102      return false;
2103    if (!BranchWritePC(context, target))
2104      return false;
2105    if (m_opcode_cpsr != m_new_inst_cpsr)
2106      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2107                                 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2108        return false;
2109  }
2110  return true;
2111}
2112
2113// Branch with Link and Exchange (register) calls a subroutine at an address and
2114// instruction set specified by a register.
2115// BLX (register)
2116bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2117                                         const ARMEncoding encoding) {
2118#if 0
2119    // ARM pseudo code...
2120    if (ConditionPassed())
2121    {
2122        EncodingSpecificOperations();
2123        target = R[m];
2124        if CurrentInstrSet() == InstrSet_ARM then
2125            next_instr_addr = PC - 4;
2126            LR = next_instr_addr;
2127        else
2128            next_instr_addr = PC - 2;
2129            LR = next_instr_addr<31:1> : '1';
2130        BXWritePC(target);
2131    }
2132#endif
2133
2134  bool success = false;
2135
2136  if (ConditionPassed(opcode)) {
2137    EmulateInstruction::Context context;
2138    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2139    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2140    addr_t lr; // next instruction address
2141    if (!success)
2142      return false;
2143    uint32_t Rm; // the register with the target address
2144    switch (encoding) {
2145    case eEncodingT1:
2146      lr = (pc - 2) | 1u; // return address
2147      Rm = Bits32(opcode, 6, 3);
2148      // if m == 15 then UNPREDICTABLE;
2149      if (Rm == 15)
2150        return false;
2151      if (InITBlock() && !LastInITBlock())
2152        return false;
2153      break;
2154    case eEncodingA1:
2155      lr = pc - 4; // return address
2156      Rm = Bits32(opcode, 3, 0);
2157      // if m == 15 then UNPREDICTABLE;
2158      if (Rm == 15)
2159        return false;
2160      break;
2161    default:
2162      return false;
2163    }
2164    addr_t target = ReadCoreReg(Rm, &success);
2165    if (!success)
2166      return false;
2167    RegisterInfo dwarf_reg;
2168    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2169    context.SetRegister(dwarf_reg);
2170    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2171                               LLDB_REGNUM_GENERIC_RA, lr))
2172      return false;
2173    if (!BXWritePC(context, target))
2174      return false;
2175  }
2176  return true;
2177}
2178
2179// Branch and Exchange causes a branch to an address and instruction set
2180// specified by a register.
2181bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2182                                        const ARMEncoding encoding) {
2183#if 0
2184    // ARM pseudo code...
2185    if (ConditionPassed())
2186    {
2187        EncodingSpecificOperations();
2188        BXWritePC(R[m]);
2189    }
2190#endif
2191
2192  if (ConditionPassed(opcode)) {
2193    EmulateInstruction::Context context;
2194    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2195    uint32_t Rm; // the register with the target address
2196    switch (encoding) {
2197    case eEncodingT1:
2198      Rm = Bits32(opcode, 6, 3);
2199      if (InITBlock() && !LastInITBlock())
2200        return false;
2201      break;
2202    case eEncodingA1:
2203      Rm = Bits32(opcode, 3, 0);
2204      break;
2205    default:
2206      return false;
2207    }
2208    bool success = false;
2209    addr_t target = ReadCoreReg(Rm, &success);
2210    if (!success)
2211      return false;
2212
2213    RegisterInfo dwarf_reg;
2214    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2215    context.SetRegister(dwarf_reg);
2216    if (!BXWritePC(context, target))
2217      return false;
2218  }
2219  return true;
2220}
2221
2222// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2223// attempt fails, it branches to an
2224// address and instruction set specified by a register as though it were a BX
2225// instruction.
2226//
2227// TODO: Emulate Jazelle architecture?
2228//       We currently assume that switching to Jazelle state fails, thus
2229//       treating BXJ as a BX operation.
2230bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2231                                         const ARMEncoding encoding) {
2232#if 0
2233    // ARM pseudo code...
2234    if (ConditionPassed())
2235    {
2236        EncodingSpecificOperations();
2237        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2238            BXWritePC(R[m]);
2239        else
2240            if JazelleAcceptsExecution() then
2241                SwitchToJazelleExecution();
2242            else
2243                SUBARCHITECTURE_DEFINED handler call;
2244    }
2245#endif
2246
2247  if (ConditionPassed(opcode)) {
2248    EmulateInstruction::Context context;
2249    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2250    uint32_t Rm; // the register with the target address
2251    switch (encoding) {
2252    case eEncodingT1:
2253      Rm = Bits32(opcode, 19, 16);
2254      if (BadReg(Rm))
2255        return false;
2256      if (InITBlock() && !LastInITBlock())
2257        return false;
2258      break;
2259    case eEncodingA1:
2260      Rm = Bits32(opcode, 3, 0);
2261      if (Rm == 15)
2262        return false;
2263      break;
2264    default:
2265      return false;
2266    }
2267    bool success = false;
2268    addr_t target = ReadCoreReg(Rm, &success);
2269    if (!success)
2270      return false;
2271
2272    RegisterInfo dwarf_reg;
2273    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2274    context.SetRegister(dwarf_reg);
2275    if (!BXWritePC(context, target))
2276      return false;
2277  }
2278  return true;
2279}
2280
2281// Set r7 to point to some ip offset.
2282// SUB (immediate)
2283bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2284                                              const ARMEncoding encoding) {
2285#if 0
2286    // ARM pseudo code...
2287    if (ConditionPassed())
2288    {
2289        EncodingSpecificOperations();
2290        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2291        if d == 15 then // Can only occur for ARM encoding
2292           ALUWritePC(result); // setflags is always FALSE here
2293        else
2294            R[d] = result;
2295            if setflags then
2296                APSR.N = result<31>;
2297                APSR.Z = IsZeroBit(result);
2298                APSR.C = carry;
2299                APSR.V = overflow;
2300    }
2301#endif
2302
2303  if (ConditionPassed(opcode)) {
2304    bool success = false;
2305    const addr_t ip = ReadCoreReg(12, &success);
2306    if (!success)
2307      return false;
2308    uint32_t imm32;
2309    switch (encoding) {
2310    case eEncodingA1:
2311      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2312      break;
2313    default:
2314      return false;
2315    }
2316    addr_t ip_offset = imm32;
2317    addr_t addr = ip - ip_offset; // the adjusted ip value
2318
2319    EmulateInstruction::Context context;
2320    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2321    RegisterInfo dwarf_reg;
2322    GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2323    context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2324
2325    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2326      return false;
2327  }
2328  return true;
2329}
2330
2331// Set ip to point to some stack offset.
2332// SUB (SP minus immediate)
2333bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2334                                              const ARMEncoding encoding) {
2335#if 0
2336    // ARM pseudo code...
2337    if (ConditionPassed())
2338    {
2339        EncodingSpecificOperations();
2340        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2341        if d == 15 then // Can only occur for ARM encoding
2342           ALUWritePC(result); // setflags is always FALSE here
2343        else
2344            R[d] = result;
2345            if setflags then
2346                APSR.N = result<31>;
2347                APSR.Z = IsZeroBit(result);
2348                APSR.C = carry;
2349                APSR.V = overflow;
2350    }
2351#endif
2352
2353  if (ConditionPassed(opcode)) {
2354    bool success = false;
2355    const addr_t sp = ReadCoreReg(SP_REG, &success);
2356    if (!success)
2357      return false;
2358    uint32_t imm32;
2359    switch (encoding) {
2360    case eEncodingA1:
2361      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2362      break;
2363    default:
2364      return false;
2365    }
2366    addr_t sp_offset = imm32;
2367    addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2368
2369    EmulateInstruction::Context context;
2370    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2371    RegisterInfo dwarf_reg;
2372    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2373    context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2374
2375    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2376      return false;
2377  }
2378  return true;
2379}
2380
2381// This instruction subtracts an immediate value from the SP value, and writes
2382// the result to the destination register.
2383//
2384// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2385// storage.
2386bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2387                                            const ARMEncoding encoding) {
2388#if 0
2389    // ARM pseudo code...
2390    if (ConditionPassed())
2391    {
2392        EncodingSpecificOperations();
2393        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2394        if d == 15 then        // Can only occur for ARM encoding
2395           ALUWritePC(result); // setflags is always FALSE here
2396        else
2397            R[d] = result;
2398            if setflags then
2399                APSR.N = result<31>;
2400                APSR.Z = IsZeroBit(result);
2401                APSR.C = carry;
2402                APSR.V = overflow;
2403    }
2404#endif
2405
2406  bool success = false;
2407  if (ConditionPassed(opcode)) {
2408    const addr_t sp = ReadCoreReg(SP_REG, &success);
2409    if (!success)
2410      return false;
2411
2412    uint32_t Rd;
2413    bool setflags;
2414    uint32_t imm32;
2415    switch (encoding) {
2416    case eEncodingT1:
2417      Rd = 13;
2418      setflags = false;
2419      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2420      break;
2421    case eEncodingT2:
2422      Rd = Bits32(opcode, 11, 8);
2423      setflags = BitIsSet(opcode, 20);
2424      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2425      if (Rd == 15 && setflags)
2426        return EmulateCMPImm(opcode, eEncodingT2);
2427      if (Rd == 15 && !setflags)
2428        return false;
2429      break;
2430    case eEncodingT3:
2431      Rd = Bits32(opcode, 11, 8);
2432      setflags = false;
2433      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2434      if (Rd == 15)
2435        return false;
2436      break;
2437    case eEncodingA1:
2438      Rd = Bits32(opcode, 15, 12);
2439      setflags = BitIsSet(opcode, 20);
2440      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2441
2442      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2443      // instructions;
2444      if (Rd == 15 && setflags)
2445        return EmulateSUBSPcLrEtc(opcode, encoding);
2446      break;
2447    default:
2448      return false;
2449    }
2450    AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2451
2452    EmulateInstruction::Context context;
2453    if (Rd == 13) {
2454      uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2455                              // to negate it, or the wrong
2456      // value gets passed down to context.SetImmediateSigned.
2457      context.type = EmulateInstruction::eContextAdjustStackPointer;
2458      context.SetImmediateSigned(-imm64); // the stack pointer offset
2459    } else {
2460      context.type = EmulateInstruction::eContextImmediate;
2461      context.SetNoArgs();
2462    }
2463
2464    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2465                                   res.carry_out, res.overflow))
2466      return false;
2467  }
2468  return true;
2469}
2470
2471// A store operation to the stack that also updates the SP.
2472bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2473                                           const ARMEncoding encoding) {
2474#if 0
2475    // ARM pseudo code...
2476    if (ConditionPassed())
2477    {
2478        EncodingSpecificOperations();
2479        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2480        address = if index then offset_addr else R[n];
2481        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2482        if wback then R[n] = offset_addr;
2483    }
2484#endif
2485
2486  bool success = false;
2487  if (ConditionPassed(opcode)) {
2488    const uint32_t addr_byte_size = GetAddressByteSize();
2489    const addr_t sp = ReadCoreReg(SP_REG, &success);
2490    if (!success)
2491      return false;
2492    uint32_t Rt; // the source register
2493    uint32_t imm12;
2494    uint32_t
2495        Rn; // This function assumes Rn is the SP, but we should verify that.
2496
2497    bool index;
2498    bool add;
2499    bool wback;
2500    switch (encoding) {
2501    case eEncodingA1:
2502      Rt = Bits32(opcode, 15, 12);
2503      imm12 = Bits32(opcode, 11, 0);
2504      Rn = Bits32(opcode, 19, 16);
2505
2506      if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2507        return false;
2508
2509      index = BitIsSet(opcode, 24);
2510      add = BitIsSet(opcode, 23);
2511      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2512
2513      if (wback && ((Rn == 15) || (Rn == Rt)))
2514        return false;
2515      break;
2516    default:
2517      return false;
2518    }
2519    addr_t offset_addr;
2520    if (add)
2521      offset_addr = sp + imm12;
2522    else
2523      offset_addr = sp - imm12;
2524
2525    addr_t addr;
2526    if (index)
2527      addr = offset_addr;
2528    else
2529      addr = sp;
2530
2531    EmulateInstruction::Context context;
2532    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2533    RegisterInfo sp_reg;
2534    RegisterInfo dwarf_reg;
2535
2536    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2537    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2538    context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2539    if (Rt != 15) {
2540      uint32_t reg_value = ReadCoreReg(Rt, &success);
2541      if (!success)
2542        return false;
2543      if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2544        return false;
2545    } else {
2546      const uint32_t pc = ReadCoreReg(PC_REG, &success);
2547      if (!success)
2548        return false;
2549      if (!MemUWrite(context, addr, pc, addr_byte_size))
2550        return false;
2551    }
2552
2553    if (wback) {
2554      context.type = EmulateInstruction::eContextAdjustStackPointer;
2555      context.SetImmediateSigned(addr - sp);
2556      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2557                                 LLDB_REGNUM_GENERIC_SP, offset_addr))
2558        return false;
2559    }
2560  }
2561  return true;
2562}
2563
2564// Vector Push stores multiple extension registers to the stack.
2565// It also updates SP to point to the start of the stored data.
2566bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2567                                         const ARMEncoding encoding) {
2568#if 0
2569    // ARM pseudo code...
2570    if (ConditionPassed())
2571    {
2572        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2573        address = SP - imm32;
2574        SP = SP - imm32;
2575        if single_regs then
2576            for r = 0 to regs-1
2577                MemA[address,4] = S[d+r]; address = address+4;
2578        else
2579            for r = 0 to regs-1
2580                // Store as two word-aligned words in the correct order for current endianness.
2581                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2582                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2583                address = address+8;
2584    }
2585#endif
2586
2587  bool success = false;
2588  if (ConditionPassed(opcode)) {
2589    const uint32_t addr_byte_size = GetAddressByteSize();
2590    const addr_t sp = ReadCoreReg(SP_REG, &success);
2591    if (!success)
2592      return false;
2593    bool single_regs;
2594    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2595    uint32_t imm32; // stack offset
2596    uint32_t regs;  // number of registers
2597    switch (encoding) {
2598    case eEncodingT1:
2599    case eEncodingA1:
2600      single_regs = false;
2601      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2602      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2603      // If UInt(imm8) is odd, see "FSTMX".
2604      regs = Bits32(opcode, 7, 0) / 2;
2605      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2606      if (regs == 0 || regs > 16 || (d + regs) > 32)
2607        return false;
2608      break;
2609    case eEncodingT2:
2610    case eEncodingA2:
2611      single_regs = true;
2612      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2613      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2614      regs = Bits32(opcode, 7, 0);
2615      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2616      if (regs == 0 || regs > 16 || (d + regs) > 32)
2617        return false;
2618      break;
2619    default:
2620      return false;
2621    }
2622    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2623    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2624    addr_t sp_offset = imm32;
2625    addr_t addr = sp - sp_offset;
2626    uint32_t i;
2627
2628    EmulateInstruction::Context context;
2629    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2630
2631    RegisterInfo dwarf_reg;
2632    RegisterInfo sp_reg;
2633    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2634    for (i = 0; i < regs; ++i) {
2635      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2636      context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2637      // uint64_t to accommodate 64-bit registers.
2638      uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2639      if (!success)
2640        return false;
2641      if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2642        return false;
2643      addr += reg_byte_size;
2644    }
2645
2646    context.type = EmulateInstruction::eContextAdjustStackPointer;
2647    context.SetImmediateSigned(-sp_offset);
2648
2649    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2650                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2651      return false;
2652  }
2653  return true;
2654}
2655
2656// Vector Pop loads multiple extension registers from the stack.
2657// It also updates SP to point just above the loaded data.
2658bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2659                                        const ARMEncoding encoding) {
2660#if 0
2661    // ARM pseudo code...
2662    if (ConditionPassed())
2663    {
2664        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2665        address = SP;
2666        SP = SP + imm32;
2667        if single_regs then
2668            for r = 0 to regs-1
2669                S[d+r] = MemA[address,4]; address = address+4;
2670        else
2671            for r = 0 to regs-1
2672                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2673                // Combine the word-aligned words in the correct order for current endianness.
2674                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2675    }
2676#endif
2677
2678  bool success = false;
2679  if (ConditionPassed(opcode)) {
2680    const uint32_t addr_byte_size = GetAddressByteSize();
2681    const addr_t sp = ReadCoreReg(SP_REG, &success);
2682    if (!success)
2683      return false;
2684    bool single_regs;
2685    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2686    uint32_t imm32; // stack offset
2687    uint32_t regs;  // number of registers
2688    switch (encoding) {
2689    case eEncodingT1:
2690    case eEncodingA1:
2691      single_regs = false;
2692      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2693      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2694      // If UInt(imm8) is odd, see "FLDMX".
2695      regs = Bits32(opcode, 7, 0) / 2;
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    case eEncodingT2:
2701    case eEncodingA2:
2702      single_regs = true;
2703      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2704      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2705      regs = Bits32(opcode, 7, 0);
2706      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2707      if (regs == 0 || regs > 16 || (d + regs) > 32)
2708        return false;
2709      break;
2710    default:
2711      return false;
2712    }
2713    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2714    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2715    addr_t sp_offset = imm32;
2716    addr_t addr = sp;
2717    uint32_t i;
2718    uint64_t data; // uint64_t to accommodate 64-bit registers.
2719
2720    EmulateInstruction::Context context;
2721    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2722
2723    RegisterInfo dwarf_reg;
2724    RegisterInfo sp_reg;
2725    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2726    for (i = 0; i < regs; ++i) {
2727      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2728      context.SetAddress(addr);
2729      data = MemARead(context, addr, reg_byte_size, 0, &success);
2730      if (!success)
2731        return false;
2732      if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2733        return false;
2734      addr += reg_byte_size;
2735    }
2736
2737    context.type = EmulateInstruction::eContextAdjustStackPointer;
2738    context.SetImmediateSigned(sp_offset);
2739
2740    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2741                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2742      return false;
2743  }
2744  return true;
2745}
2746
2747// SVC (previously SWI)
2748bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2749                                       const ARMEncoding encoding) {
2750#if 0
2751    // ARM pseudo code...
2752    if (ConditionPassed())
2753    {
2754        EncodingSpecificOperations();
2755        CallSupervisor();
2756    }
2757#endif
2758
2759  bool success = false;
2760
2761  if (ConditionPassed(opcode)) {
2762    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2763    addr_t lr; // next instruction address
2764    if (!success)
2765      return false;
2766    uint32_t imm32; // the immediate constant
2767    uint32_t mode;  // ARM or Thumb mode
2768    switch (encoding) {
2769    case eEncodingT1:
2770      lr = (pc + 2) | 1u; // return address
2771      imm32 = Bits32(opcode, 7, 0);
2772      mode = eModeThumb;
2773      break;
2774    case eEncodingA1:
2775      lr = pc + 4; // return address
2776      imm32 = Bits32(opcode, 23, 0);
2777      mode = eModeARM;
2778      break;
2779    default:
2780      return false;
2781    }
2782
2783    EmulateInstruction::Context context;
2784    context.type = EmulateInstruction::eContextSupervisorCall;
2785    context.SetISAAndImmediate(mode, imm32);
2786    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2787                               LLDB_REGNUM_GENERIC_RA, lr))
2788      return false;
2789  }
2790  return true;
2791}
2792
2793// If Then makes up to four following instructions (the IT block) conditional.
2794bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2795                                      const ARMEncoding encoding) {
2796#if 0
2797    // ARM pseudo code...
2798    EncodingSpecificOperations();
2799    ITSTATE.IT<7:0> = firstcond:mask;
2800#endif
2801
2802  m_it_session.InitIT(Bits32(opcode, 7, 0));
2803  return true;
2804}
2805
2806bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2807                                       const ARMEncoding encoding) {
2808  // NOP, nothing to do...
2809  return true;
2810}
2811
2812// Branch causes a branch to a target address.
2813bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2814                                     const ARMEncoding encoding) {
2815#if 0
2816    // ARM pseudo code...
2817    if (ConditionPassed())
2818    {
2819        EncodingSpecificOperations();
2820        BranchWritePC(PC + imm32);
2821    }
2822#endif
2823
2824  bool success = false;
2825
2826  if (ConditionPassed(opcode)) {
2827    EmulateInstruction::Context context;
2828    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2829    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2830    if (!success)
2831      return false;
2832    addr_t target; // target address
2833    int32_t imm32; // PC-relative offset
2834    switch (encoding) {
2835    case eEncodingT1:
2836      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2837      imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2838      target = pc + imm32;
2839      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2840      break;
2841    case eEncodingT2:
2842      imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2843      target = pc + imm32;
2844      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2845      break;
2846    case eEncodingT3:
2847      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2848      {
2849        if (Bits32(opcode, 25, 23) == 7)
2850          return false; // See Branches and miscellaneous control on page
2851                        // A6-235.
2852
2853        uint32_t S = Bit32(opcode, 26);
2854        uint32_t imm6 = Bits32(opcode, 21, 16);
2855        uint32_t J1 = Bit32(opcode, 13);
2856        uint32_t J2 = Bit32(opcode, 11);
2857        uint32_t imm11 = Bits32(opcode, 10, 0);
2858        uint32_t imm21 =
2859            (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2860        imm32 = llvm::SignExtend32<21>(imm21);
2861        target = pc + imm32;
2862        context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2863        break;
2864      }
2865    case eEncodingT4: {
2866      uint32_t S = Bit32(opcode, 26);
2867      uint32_t imm10 = Bits32(opcode, 25, 16);
2868      uint32_t J1 = Bit32(opcode, 13);
2869      uint32_t J2 = Bit32(opcode, 11);
2870      uint32_t imm11 = Bits32(opcode, 10, 0);
2871      uint32_t I1 = !(J1 ^ S);
2872      uint32_t I2 = !(J2 ^ S);
2873      uint32_t imm25 =
2874          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2875      imm32 = llvm::SignExtend32<25>(imm25);
2876      target = pc + imm32;
2877      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2878      break;
2879    }
2880    case eEncodingA1:
2881      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2882      target = pc + imm32;
2883      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2884      break;
2885    default:
2886      return false;
2887    }
2888    if (!BranchWritePC(context, target))
2889      return false;
2890  }
2891  return true;
2892}
2893
2894// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2895// value in a register with
2896// zero and conditionally branch forward a constant value.  They do not affect
2897// the condition flags.
2898// CBNZ, CBZ
2899bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2900                                      const ARMEncoding encoding) {
2901#if 0
2902    // ARM pseudo code...
2903    EncodingSpecificOperations();
2904    if nonzero ^ IsZero(R[n]) then
2905        BranchWritePC(PC + imm32);
2906#endif
2907
2908  bool success = false;
2909
2910  // Read the register value from the operand register Rn.
2911  uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2912  if (!success)
2913    return false;
2914
2915  EmulateInstruction::Context context;
2916  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2917  const uint32_t pc = ReadCoreReg(PC_REG, &success);
2918  if (!success)
2919    return false;
2920
2921  addr_t target;  // target address
2922  uint32_t imm32; // PC-relative offset to branch forward
2923  bool nonzero;
2924  switch (encoding) {
2925  case eEncodingT1:
2926    imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2927    nonzero = BitIsSet(opcode, 11);
2928    target = pc + imm32;
2929    context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2930    break;
2931  default:
2932    return false;
2933  }
2934  if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2935    if (!BranchWritePC(context, target))
2936      return false;
2937
2938  return true;
2939}
2940
2941// Table Branch Byte causes a PC-relative forward branch using a table of single
2942// byte offsets.
2943// A base register provides a pointer to the table, and a second register
2944// supplies an index into the table.
2945// The branch length is twice the value of the byte returned from the table.
2946//
2947// Table Branch Halfword causes a PC-relative forward branch using a table of
2948// single halfword offsets.
2949// A base register provides a pointer to the table, and a second register
2950// supplies an index into the table.
2951// The branch length is twice the value of the halfword returned from the table.
2952// TBB, TBH
2953bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2954                                      const ARMEncoding encoding) {
2955#if 0
2956    // ARM pseudo code...
2957    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2958    if is_tbh then
2959        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2960    else
2961        halfwords = UInt(MemU[R[n]+R[m], 1]);
2962    BranchWritePC(PC + 2*halfwords);
2963#endif
2964
2965  bool success = false;
2966
2967  if (ConditionPassed(opcode)) {
2968    uint32_t Rn; // the base register which contains the address of the table of
2969                 // branch lengths
2970    uint32_t Rm; // the index register which contains an integer pointing to a
2971                 // byte/halfword in the table
2972    bool is_tbh; // true if table branch halfword
2973    switch (encoding) {
2974    case eEncodingT1:
2975      Rn = Bits32(opcode, 19, 16);
2976      Rm = Bits32(opcode, 3, 0);
2977      is_tbh = BitIsSet(opcode, 4);
2978      if (Rn == 13 || BadReg(Rm))
2979        return false;
2980      if (InITBlock() && !LastInITBlock())
2981        return false;
2982      break;
2983    default:
2984      return false;
2985    }
2986
2987    // Read the address of the table from the operand register Rn.
2988    // The PC can be used, in which case the table immediately follows this
2989    // instruction.
2990    uint32_t base = ReadCoreReg(Rn, &success);
2991    if (!success)
2992      return false;
2993
2994    // the table index
2995    uint32_t index = ReadCoreReg(Rm, &success);
2996    if (!success)
2997      return false;
2998
2999    // the offsetted table address
3000    addr_t addr = base + (is_tbh ? index * 2 : index);
3001
3002    // PC-relative offset to branch forward
3003    EmulateInstruction::Context context;
3004    context.type = EmulateInstruction::eContextTableBranchReadMemory;
3005    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
3006    if (!success)
3007      return false;
3008
3009    const uint32_t pc = ReadCoreReg(PC_REG, &success);
3010    if (!success)
3011      return false;
3012
3013    // target address
3014    addr_t target = pc + offset;
3015    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3016    context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3017
3018    if (!BranchWritePC(context, target))
3019      return false;
3020  }
3021
3022  return true;
3023}
3024
3025// This instruction adds an immediate value to a register value, and writes the
3026// result to the destination register.
3027// It can optionally update the condition flags based on the result.
3028bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3029                                               const ARMEncoding encoding) {
3030#if 0
3031    if ConditionPassed() then
3032        EncodingSpecificOperations();
3033        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3034        R[d] = result;
3035        if setflags then
3036            APSR.N = result<31>;
3037            APSR.Z = IsZeroBit(result);
3038            APSR.C = carry;
3039            APSR.V = overflow;
3040#endif
3041
3042  bool success = false;
3043
3044  if (ConditionPassed(opcode)) {
3045    uint32_t d;
3046    uint32_t n;
3047    bool setflags;
3048    uint32_t imm32;
3049    uint32_t carry_out;
3050
3051    // EncodingSpecificOperations();
3052    switch (encoding) {
3053    case eEncodingT1:
3054      // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3055      // ZeroExtend(imm3, 32);
3056      d = Bits32(opcode, 2, 0);
3057      n = Bits32(opcode, 5, 3);
3058      setflags = !InITBlock();
3059      imm32 = Bits32(opcode, 8, 6);
3060
3061      break;
3062
3063    case eEncodingT2:
3064      // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3065      // ZeroExtend(imm8, 32);
3066      d = Bits32(opcode, 10, 8);
3067      n = Bits32(opcode, 10, 8);
3068      setflags = !InITBlock();
3069      imm32 = Bits32(opcode, 7, 0);
3070
3071      break;
3072
3073    case eEncodingT3:
3074      // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3075      // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3076      // ThumbExpandImm(i:imm3:imm8);
3077      d = Bits32(opcode, 11, 8);
3078      n = Bits32(opcode, 19, 16);
3079      setflags = BitIsSet(opcode, 20);
3080      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3081
3082      // if Rn == '1101' then SEE ADD (SP plus immediate);
3083      if (n == 13)
3084        return EmulateADDSPImm(opcode, eEncodingT3);
3085
3086      // if BadReg(d) || n == 15 then UNPREDICTABLE;
3087      if (BadReg(d) || (n == 15))
3088        return false;
3089
3090      break;
3091
3092    case eEncodingT4: {
3093      // if Rn == '1111' then SEE ADR;
3094      // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3095      // ZeroExtend(i:imm3:imm8, 32);
3096      d = Bits32(opcode, 11, 8);
3097      n = Bits32(opcode, 19, 16);
3098      setflags = false;
3099      uint32_t i = Bit32(opcode, 26);
3100      uint32_t imm3 = Bits32(opcode, 14, 12);
3101      uint32_t imm8 = Bits32(opcode, 7, 0);
3102      imm32 = (i << 11) | (imm3 << 8) | imm8;
3103
3104      // if Rn == '1101' then SEE ADD (SP plus immediate);
3105      if (n == 13)
3106        return EmulateADDSPImm(opcode, eEncodingT4);
3107
3108      // if BadReg(d) then UNPREDICTABLE;
3109      if (BadReg(d))
3110        return false;
3111
3112      break;
3113    }
3114
3115    default:
3116      return false;
3117    }
3118
3119    uint64_t Rn =
3120        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3121    if (!success)
3122      return false;
3123
3124    //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3125    AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3126
3127    RegisterInfo reg_n;
3128    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3129
3130    EmulateInstruction::Context context;
3131    context.type = eContextArithmetic;
3132    context.SetRegisterPlusOffset(reg_n, imm32);
3133
3134    // R[d] = result;
3135    // if setflags then
3136    // APSR.N = result<31>;
3137    // APSR.Z = IsZeroBit(result);
3138    // APSR.C = carry;
3139    // APSR.V = overflow;
3140    if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3141                                   res.carry_out, res.overflow))
3142      return false;
3143  }
3144  return true;
3145}
3146
3147// This instruction adds an immediate value to a register value, and writes the
3148// result to the destination
3149// register.  It can optionally update the condition flags based on the result.
3150bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3151                                             const ARMEncoding encoding) {
3152#if 0
3153    // ARM pseudo code...
3154    if ConditionPassed() then
3155        EncodingSpecificOperations();
3156        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3157        if d == 15 then
3158            ALUWritePC(result); // setflags is always FALSE here
3159        else
3160            R[d] = result;
3161            if setflags then
3162                APSR.N = result<31>;
3163                APSR.Z = IsZeroBit(result);
3164                APSR.C = carry;
3165                APSR.V = overflow;
3166#endif
3167
3168  bool success = false;
3169
3170  if (ConditionPassed(opcode)) {
3171    uint32_t Rd, Rn;
3172    uint32_t
3173        imm32; // the immediate value to be added to the value obtained from Rn
3174    bool setflags;
3175    switch (encoding) {
3176    case eEncodingA1:
3177      Rd = Bits32(opcode, 15, 12);
3178      Rn = Bits32(opcode, 19, 16);
3179      setflags = BitIsSet(opcode, 20);
3180      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3181      break;
3182    default:
3183      return false;
3184    }
3185
3186    // Read the first operand.
3187    uint32_t val1 = ReadCoreReg(Rn, &success);
3188    if (!success)
3189      return false;
3190
3191    AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3192
3193    EmulateInstruction::Context context;
3194    if (Rd == 13)
3195      context.type = EmulateInstruction::eContextAdjustStackPointer;
3196    else if (Rd == GetFramePointerRegisterNumber())
3197      context.type = EmulateInstruction::eContextSetFramePointer;
3198    else
3199      context.type = EmulateInstruction::eContextRegisterPlusOffset;
3200
3201    RegisterInfo dwarf_reg;
3202    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3203    context.SetRegisterPlusOffset(dwarf_reg, imm32);
3204
3205    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3206                                   res.carry_out, res.overflow))
3207      return false;
3208  }
3209  return true;
3210}
3211
3212// This instruction adds a register value and an optionally-shifted register
3213// value, and writes the result
3214// to the destination register. It can optionally update the condition flags
3215// based on the result.
3216bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3217                                          const ARMEncoding encoding) {
3218#if 0
3219    // ARM pseudo code...
3220    if ConditionPassed() then
3221        EncodingSpecificOperations();
3222        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3223        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3224        if d == 15 then
3225            ALUWritePC(result); // setflags is always FALSE here
3226        else
3227            R[d] = result;
3228            if setflags then
3229                APSR.N = result<31>;
3230                APSR.Z = IsZeroBit(result);
3231                APSR.C = carry;
3232                APSR.V = overflow;
3233#endif
3234
3235  bool success = false;
3236
3237  if (ConditionPassed(opcode)) {
3238    uint32_t Rd, Rn, Rm;
3239    ARM_ShifterType shift_t;
3240    uint32_t shift_n; // the shift applied to the value read from Rm
3241    bool setflags;
3242    switch (encoding) {
3243    case eEncodingT1:
3244      Rd = Bits32(opcode, 2, 0);
3245      Rn = Bits32(opcode, 5, 3);
3246      Rm = Bits32(opcode, 8, 6);
3247      setflags = !InITBlock();
3248      shift_t = SRType_LSL;
3249      shift_n = 0;
3250      break;
3251    case eEncodingT2:
3252      Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3253      Rm = Bits32(opcode, 6, 3);
3254      setflags = false;
3255      shift_t = SRType_LSL;
3256      shift_n = 0;
3257      if (Rn == 15 && Rm == 15)
3258        return false;
3259      if (Rd == 15 && InITBlock() && !LastInITBlock())
3260        return false;
3261      break;
3262    case eEncodingA1:
3263      Rd = Bits32(opcode, 15, 12);
3264      Rn = Bits32(opcode, 19, 16);
3265      Rm = Bits32(opcode, 3, 0);
3266      setflags = BitIsSet(opcode, 20);
3267      shift_n = DecodeImmShiftARM(opcode, shift_t);
3268      break;
3269    default:
3270      return false;
3271    }
3272
3273    // Read the first operand.
3274    uint32_t val1 = ReadCoreReg(Rn, &success);
3275    if (!success)
3276      return false;
3277
3278    // Read the second operand.
3279    uint32_t val2 = ReadCoreReg(Rm, &success);
3280    if (!success)
3281      return false;
3282
3283    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3284    if (!success)
3285      return false;
3286    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3287
3288    EmulateInstruction::Context context;
3289    context.type = eContextArithmetic;
3290    RegisterInfo op1_reg;
3291    RegisterInfo op2_reg;
3292    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3293    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3294    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3295
3296    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3297                                   res.carry_out, res.overflow))
3298      return false;
3299  }
3300  return true;
3301}
3302
3303// Compare Negative (immediate) adds a register value and an immediate value.
3304// It updates the condition flags based on the result, and discards the result.
3305bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3306                                          const ARMEncoding encoding) {
3307#if 0
3308    // ARM pseudo code...
3309    if ConditionPassed() then
3310        EncodingSpecificOperations();
3311        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3312        APSR.N = result<31>;
3313        APSR.Z = IsZeroBit(result);
3314        APSR.C = carry;
3315        APSR.V = overflow;
3316#endif
3317
3318  bool success = false;
3319
3320  uint32_t Rn;    // the first operand
3321  uint32_t imm32; // the immediate value to be compared with
3322  switch (encoding) {
3323  case eEncodingT1:
3324    Rn = Bits32(opcode, 19, 16);
3325    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3326    if (Rn == 15)
3327      return false;
3328    break;
3329  case eEncodingA1:
3330    Rn = Bits32(opcode, 19, 16);
3331    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3332    break;
3333  default:
3334    return false;
3335  }
3336  // Read the register value from the operand register Rn.
3337  uint32_t reg_val = ReadCoreReg(Rn, &success);
3338  if (!success)
3339    return false;
3340
3341  AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3342
3343  EmulateInstruction::Context context;
3344  context.type = EmulateInstruction::eContextImmediate;
3345  context.SetNoArgs();
3346  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3347    return false;
3348
3349  return true;
3350}
3351
3352// Compare Negative (register) adds a register value and an optionally-shifted
3353// register value.
3354// It updates the condition flags based on the result, and discards the result.
3355bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3356                                          const ARMEncoding encoding) {
3357#if 0
3358    // ARM pseudo code...
3359    if ConditionPassed() then
3360        EncodingSpecificOperations();
3361        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3362        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3363        APSR.N = result<31>;
3364        APSR.Z = IsZeroBit(result);
3365        APSR.C = carry;
3366        APSR.V = overflow;
3367#endif
3368
3369  bool success = false;
3370
3371  uint32_t Rn; // the first operand
3372  uint32_t Rm; // the second operand
3373  ARM_ShifterType shift_t;
3374  uint32_t shift_n; // the shift applied to the value read from Rm
3375  switch (encoding) {
3376  case eEncodingT1:
3377    Rn = Bits32(opcode, 2, 0);
3378    Rm = Bits32(opcode, 5, 3);
3379    shift_t = SRType_LSL;
3380    shift_n = 0;
3381    break;
3382  case eEncodingT2:
3383    Rn = Bits32(opcode, 19, 16);
3384    Rm = Bits32(opcode, 3, 0);
3385    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3386    // if n == 15 || BadReg(m) then UNPREDICTABLE;
3387    if (Rn == 15 || BadReg(Rm))
3388      return false;
3389    break;
3390  case eEncodingA1:
3391    Rn = Bits32(opcode, 19, 16);
3392    Rm = Bits32(opcode, 3, 0);
3393    shift_n = DecodeImmShiftARM(opcode, shift_t);
3394    break;
3395  default:
3396    return false;
3397  }
3398  // Read the register value from register Rn.
3399  uint32_t val1 = ReadCoreReg(Rn, &success);
3400  if (!success)
3401    return false;
3402
3403  // Read the register value from register Rm.
3404  uint32_t val2 = ReadCoreReg(Rm, &success);
3405  if (!success)
3406    return false;
3407
3408  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3409  if (!success)
3410    return false;
3411  AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3412
3413  EmulateInstruction::Context context;
3414  context.type = EmulateInstruction::eContextImmediate;
3415  context.SetNoArgs();
3416  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3417    return false;
3418
3419  return true;
3420}
3421
3422// Compare (immediate) subtracts an immediate value from a register value.
3423// It updates the condition flags based on the result, and discards the result.
3424bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3425                                          const ARMEncoding encoding) {
3426#if 0
3427    // ARM pseudo code...
3428    if ConditionPassed() then
3429        EncodingSpecificOperations();
3430        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3431        APSR.N = result<31>;
3432        APSR.Z = IsZeroBit(result);
3433        APSR.C = carry;
3434        APSR.V = overflow;
3435#endif
3436
3437  bool success = false;
3438
3439  uint32_t Rn;    // the first operand
3440  uint32_t imm32; // the immediate value to be compared with
3441  switch (encoding) {
3442  case eEncodingT1:
3443    Rn = Bits32(opcode, 10, 8);
3444    imm32 = Bits32(opcode, 7, 0);
3445    break;
3446  case eEncodingT2:
3447    Rn = Bits32(opcode, 19, 16);
3448    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3449    if (Rn == 15)
3450      return false;
3451    break;
3452  case eEncodingA1:
3453    Rn = Bits32(opcode, 19, 16);
3454    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3455    break;
3456  default:
3457    return false;
3458  }
3459  // Read the register value from the operand register Rn.
3460  uint32_t reg_val = ReadCoreReg(Rn, &success);
3461  if (!success)
3462    return false;
3463
3464  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3465
3466  EmulateInstruction::Context context;
3467  context.type = EmulateInstruction::eContextImmediate;
3468  context.SetNoArgs();
3469  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3470    return false;
3471
3472  return true;
3473}
3474
3475// Compare (register) subtracts an optionally-shifted register value from a
3476// register value.
3477// It updates the condition flags based on the result, and discards the result.
3478bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3479                                          const ARMEncoding encoding) {
3480#if 0
3481    // ARM pseudo code...
3482    if ConditionPassed() then
3483        EncodingSpecificOperations();
3484        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3485        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3486        APSR.N = result<31>;
3487        APSR.Z = IsZeroBit(result);
3488        APSR.C = carry;
3489        APSR.V = overflow;
3490#endif
3491
3492  bool success = false;
3493
3494  uint32_t Rn; // the first operand
3495  uint32_t Rm; // the second operand
3496  ARM_ShifterType shift_t;
3497  uint32_t shift_n; // the shift applied to the value read from Rm
3498  switch (encoding) {
3499  case eEncodingT1:
3500    Rn = Bits32(opcode, 2, 0);
3501    Rm = Bits32(opcode, 5, 3);
3502    shift_t = SRType_LSL;
3503    shift_n = 0;
3504    break;
3505  case eEncodingT2:
3506    Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3507    Rm = Bits32(opcode, 6, 3);
3508    shift_t = SRType_LSL;
3509    shift_n = 0;
3510    if (Rn < 8 && Rm < 8)
3511      return false;
3512    if (Rn == 15 || Rm == 15)
3513      return false;
3514    break;
3515  case eEncodingT3:
3516    Rn = Bits32(opcode, 19, 16);
3517    Rm = Bits32(opcode, 3, 0);
3518    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3519    if (Rn == 15 || BadReg(Rm))
3520      return false;
3521    break;
3522  case eEncodingA1:
3523    Rn = Bits32(opcode, 19, 16);
3524    Rm = Bits32(opcode, 3, 0);
3525    shift_n = DecodeImmShiftARM(opcode, shift_t);
3526    break;
3527  default:
3528    return false;
3529  }
3530  // Read the register value from register Rn.
3531  uint32_t val1 = ReadCoreReg(Rn, &success);
3532  if (!success)
3533    return false;
3534
3535  // Read the register value from register Rm.
3536  uint32_t val2 = ReadCoreReg(Rm, &success);
3537  if (!success)
3538    return false;
3539
3540  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3541  if (!success)
3542    return false;
3543  AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3544
3545  EmulateInstruction::Context context;
3546  context.type = EmulateInstruction::eContextImmediate;
3547  context.SetNoArgs();
3548  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3549    return false;
3550
3551  return true;
3552}
3553
3554// Arithmetic Shift Right (immediate) shifts a register value right by an
3555// immediate number of bits,
3556// shifting in copies of its sign bit, and writes the result to the destination
3557// register.  It can
3558// optionally update the condition flags based on the result.
3559bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3560                                          const ARMEncoding encoding) {
3561#if 0
3562    // ARM pseudo code...
3563    if ConditionPassed() then
3564        EncodingSpecificOperations();
3565        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3566        if d == 15 then         // Can only occur for ARM encoding
3567            ALUWritePC(result); // setflags is always FALSE here
3568        else
3569            R[d] = result;
3570            if setflags then
3571                APSR.N = result<31>;
3572                APSR.Z = IsZeroBit(result);
3573                APSR.C = carry;
3574                // APSR.V unchanged
3575#endif
3576
3577  return EmulateShiftImm(opcode, encoding, SRType_ASR);
3578}
3579
3580// Arithmetic Shift Right (register) shifts a register value right by a variable
3581// number of bits,
3582// shifting in copies of its sign bit, and writes the result to the destination
3583// register.
3584// The variable number of bits is read from the bottom byte of a register. It
3585// can optionally update
3586// the condition flags based on the result.
3587bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3588                                          const ARMEncoding encoding) {
3589#if 0
3590    // ARM pseudo code...
3591    if ConditionPassed() then
3592        EncodingSpecificOperations();
3593        shift_n = UInt(R[m]<7:0>);
3594        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3595        R[d] = result;
3596        if setflags then
3597            APSR.N = result<31>;
3598            APSR.Z = IsZeroBit(result);
3599            APSR.C = carry;
3600            // APSR.V unchanged
3601#endif
3602
3603  return EmulateShiftReg(opcode, encoding, SRType_ASR);
3604}
3605
3606// Logical Shift Left (immediate) shifts a register value left by an immediate
3607// number of bits,
3608// shifting in zeros, and writes the result to the destination register.  It can
3609// optionally
3610// update the condition flags based on the result.
3611bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3612                                          const ARMEncoding encoding) {
3613#if 0
3614    // ARM pseudo code...
3615    if ConditionPassed() then
3616        EncodingSpecificOperations();
3617        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3618        if d == 15 then         // Can only occur for ARM encoding
3619            ALUWritePC(result); // setflags is always FALSE here
3620        else
3621            R[d] = result;
3622            if setflags then
3623                APSR.N = result<31>;
3624                APSR.Z = IsZeroBit(result);
3625                APSR.C = carry;
3626                // APSR.V unchanged
3627#endif
3628
3629  return EmulateShiftImm(opcode, encoding, SRType_LSL);
3630}
3631
3632// Logical Shift Left (register) shifts a register value left by a variable
3633// number of bits,
3634// shifting in zeros, and writes the result to the destination register.  The
3635// variable number
3636// of bits is read from the bottom byte of a register. It can optionally update
3637// the condition
3638// flags based on the result.
3639bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3640                                          const ARMEncoding encoding) {
3641#if 0
3642    // ARM pseudo code...
3643    if ConditionPassed() then
3644        EncodingSpecificOperations();
3645        shift_n = UInt(R[m]<7:0>);
3646        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3647        R[d] = result;
3648        if setflags then
3649            APSR.N = result<31>;
3650            APSR.Z = IsZeroBit(result);
3651            APSR.C = carry;
3652            // APSR.V unchanged
3653#endif
3654
3655  return EmulateShiftReg(opcode, encoding, SRType_LSL);
3656}
3657
3658// Logical Shift Right (immediate) shifts a register value right by an immediate
3659// number of bits,
3660// shifting in zeros, and writes the result to the destination register.  It can
3661// optionally
3662// update the condition flags based on the result.
3663bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3664                                          const ARMEncoding encoding) {
3665#if 0
3666    // ARM pseudo code...
3667    if ConditionPassed() then
3668        EncodingSpecificOperations();
3669        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3670        if d == 15 then         // Can only occur for ARM encoding
3671            ALUWritePC(result); // setflags is always FALSE here
3672        else
3673            R[d] = result;
3674            if setflags then
3675                APSR.N = result<31>;
3676                APSR.Z = IsZeroBit(result);
3677                APSR.C = carry;
3678                // APSR.V unchanged
3679#endif
3680
3681  return EmulateShiftImm(opcode, encoding, SRType_LSR);
3682}
3683
3684// Logical Shift Right (register) shifts a register value right by a variable
3685// number of bits,
3686// shifting in zeros, and writes the result to the destination register.  The
3687// variable number
3688// of bits is read from the bottom byte of a register. It can optionally update
3689// the condition
3690// flags based on the result.
3691bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3692                                          const ARMEncoding encoding) {
3693#if 0
3694    // ARM pseudo code...
3695    if ConditionPassed() then
3696        EncodingSpecificOperations();
3697        shift_n = UInt(R[m]<7:0>);
3698        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3699        R[d] = result;
3700        if setflags then
3701            APSR.N = result<31>;
3702            APSR.Z = IsZeroBit(result);
3703            APSR.C = carry;
3704            // APSR.V unchanged
3705#endif
3706
3707  return EmulateShiftReg(opcode, encoding, SRType_LSR);
3708}
3709
3710// Rotate Right (immediate) provides the value of the contents of a register
3711// rotated by a constant value.
3712// The bits that are rotated off the right end are inserted into the vacated bit
3713// positions on the left.
3714// It can optionally update the condition flags based on the result.
3715bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3716                                          const ARMEncoding encoding) {
3717#if 0
3718    // ARM pseudo code...
3719    if ConditionPassed() then
3720        EncodingSpecificOperations();
3721        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3722        if d == 15 then         // Can only occur for ARM encoding
3723            ALUWritePC(result); // setflags is always FALSE here
3724        else
3725            R[d] = result;
3726            if setflags then
3727                APSR.N = result<31>;
3728                APSR.Z = IsZeroBit(result);
3729                APSR.C = carry;
3730                // APSR.V unchanged
3731#endif
3732
3733  return EmulateShiftImm(opcode, encoding, SRType_ROR);
3734}
3735
3736// Rotate Right (register) provides the value of the contents of a register
3737// rotated by a variable number of bits.
3738// The bits that are rotated off the right end are inserted into the vacated bit
3739// positions on the left.
3740// The variable number of bits is read from the bottom byte of a register. It
3741// can optionally update the condition
3742// flags based on the result.
3743bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3744                                          const ARMEncoding encoding) {
3745#if 0
3746    // ARM pseudo code...
3747    if ConditionPassed() then
3748        EncodingSpecificOperations();
3749        shift_n = UInt(R[m]<7:0>);
3750        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3751        R[d] = result;
3752        if setflags then
3753            APSR.N = result<31>;
3754            APSR.Z = IsZeroBit(result);
3755            APSR.C = carry;
3756            // APSR.V unchanged
3757#endif
3758
3759  return EmulateShiftReg(opcode, encoding, SRType_ROR);
3760}
3761
3762// Rotate Right with Extend provides the value of the contents of a register
3763// shifted right by one place,
3764// with the carry flag shifted into bit [31].
3765//
3766// RRX can optionally update the condition flags based on the result.
3767// In that case, bit [0] is shifted into the carry flag.
3768bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3769                                       const ARMEncoding encoding) {
3770#if 0
3771    // ARM pseudo code...
3772    if ConditionPassed() then
3773        EncodingSpecificOperations();
3774        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3775        if d == 15 then         // Can only occur for ARM encoding
3776            ALUWritePC(result); // setflags is always FALSE here
3777        else
3778            R[d] = result;
3779            if setflags then
3780                APSR.N = result<31>;
3781                APSR.Z = IsZeroBit(result);
3782                APSR.C = carry;
3783                // APSR.V unchanged
3784#endif
3785
3786  return EmulateShiftImm(opcode, encoding, SRType_RRX);
3787}
3788
3789bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3790                                            const ARMEncoding encoding,
3791                                            ARM_ShifterType shift_type) {
3792  //    assert(shift_type == SRType_ASR
3793  //           || shift_type == SRType_LSL
3794  //           || shift_type == SRType_LSR
3795  //           || shift_type == SRType_ROR
3796  //           || shift_type == SRType_RRX);
3797
3798  bool success = false;
3799
3800  if (ConditionPassed(opcode)) {
3801    uint32_t Rd;    // the destination register
3802    uint32_t Rm;    // the first operand register
3803    uint32_t imm5;  // encoding for the shift amount
3804    uint32_t carry; // the carry bit after the shift operation
3805    bool setflags;
3806
3807    // Special case handling!
3808    // A8.6.139 ROR (immediate) -- Encoding T1
3809    ARMEncoding use_encoding = encoding;
3810    if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3811      // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding
3812      // to
3813      // have the same decoding of bit fields as the other Thumb2 shift
3814      // operations.
3815      use_encoding = eEncodingT2;
3816    }
3817
3818    switch (use_encoding) {
3819    case eEncodingT1:
3820      // Due to the above special case handling!
3821      if (shift_type == SRType_ROR)
3822        return false;
3823
3824      Rd = Bits32(opcode, 2, 0);
3825      Rm = Bits32(opcode, 5, 3);
3826      setflags = !InITBlock();
3827      imm5 = Bits32(opcode, 10, 6);
3828      break;
3829    case eEncodingT2:
3830      // A8.6.141 RRX
3831      // There's no imm form of RRX instructions.
3832      if (shift_type == SRType_RRX)
3833        return false;
3834
3835      Rd = Bits32(opcode, 11, 8);
3836      Rm = Bits32(opcode, 3, 0);
3837      setflags = BitIsSet(opcode, 20);
3838      imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3839      if (BadReg(Rd) || BadReg(Rm))
3840        return false;
3841      break;
3842    case eEncodingA1:
3843      Rd = Bits32(opcode, 15, 12);
3844      Rm = Bits32(opcode, 3, 0);
3845      setflags = BitIsSet(opcode, 20);
3846      imm5 = Bits32(opcode, 11, 7);
3847      break;
3848    default:
3849      return false;
3850    }
3851
3852    // A8.6.139 ROR (immediate)
3853    if (shift_type == SRType_ROR && imm5 == 0)
3854      shift_type = SRType_RRX;
3855
3856    // Get the first operand.
3857    uint32_t value = ReadCoreReg(Rm, &success);
3858    if (!success)
3859      return false;
3860
3861    // Decode the shift amount if not RRX.
3862    uint32_t amt =
3863        (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3864
3865    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3866    if (!success)
3867      return false;
3868
3869    // The context specifies that an immediate is to be moved into Rd.
3870    EmulateInstruction::Context context;
3871    context.type = EmulateInstruction::eContextImmediate;
3872    context.SetNoArgs();
3873
3874    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3875      return false;
3876  }
3877  return true;
3878}
3879
3880bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3881                                            const ARMEncoding encoding,
3882                                            ARM_ShifterType shift_type) {
3883  // assert(shift_type == SRType_ASR
3884  //        || shift_type == SRType_LSL
3885  //        || shift_type == SRType_LSR
3886  //        || shift_type == SRType_ROR);
3887
3888  bool success = false;
3889
3890  if (ConditionPassed(opcode)) {
3891    uint32_t Rd; // the destination register
3892    uint32_t Rn; // the first operand register
3893    uint32_t
3894        Rm; // the register whose bottom byte contains the amount to shift by
3895    uint32_t carry; // the carry bit after the shift operation
3896    bool setflags;
3897    switch (encoding) {
3898    case eEncodingT1:
3899      Rd = Bits32(opcode, 2, 0);
3900      Rn = Rd;
3901      Rm = Bits32(opcode, 5, 3);
3902      setflags = !InITBlock();
3903      break;
3904    case eEncodingT2:
3905      Rd = Bits32(opcode, 11, 8);
3906      Rn = Bits32(opcode, 19, 16);
3907      Rm = Bits32(opcode, 3, 0);
3908      setflags = BitIsSet(opcode, 20);
3909      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3910        return false;
3911      break;
3912    case eEncodingA1:
3913      Rd = Bits32(opcode, 15, 12);
3914      Rn = Bits32(opcode, 3, 0);
3915      Rm = Bits32(opcode, 11, 8);
3916      setflags = BitIsSet(opcode, 20);
3917      if (Rd == 15 || Rn == 15 || Rm == 15)
3918        return false;
3919      break;
3920    default:
3921      return false;
3922    }
3923
3924    // Get the first operand.
3925    uint32_t value = ReadCoreReg(Rn, &success);
3926    if (!success)
3927      return false;
3928    // Get the Rm register content.
3929    uint32_t val = ReadCoreReg(Rm, &success);
3930    if (!success)
3931      return false;
3932
3933    // Get the shift amount.
3934    uint32_t amt = Bits32(val, 7, 0);
3935
3936    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3937    if (!success)
3938      return false;
3939
3940    // The context specifies that an immediate is to be moved into Rd.
3941    EmulateInstruction::Context context;
3942    context.type = EmulateInstruction::eContextImmediate;
3943    context.SetNoArgs();
3944
3945    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3946      return false;
3947  }
3948  return true;
3949}
3950
3951// LDM loads multiple registers from consecutive memory locations, using an
3952// address from a base register.  Optionally the address just above the highest
3953// of those locations
3954// can be written back to the base register.
3955bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3956                                       const ARMEncoding encoding) {
3957#if 0
3958    // ARM pseudo code...
3959    if ConditionPassed()
3960        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3961        address = R[n];
3962
3963        for i = 0 to 14
3964            if registers<i> == '1' then
3965                R[i] = MemA[address, 4]; address = address + 4;
3966        if registers<15> == '1' then
3967            LoadWritePC (MemA[address, 4]);
3968
3969        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3970        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3971
3972#endif
3973
3974  bool success = false;
3975  if (ConditionPassed(opcode)) {
3976    uint32_t n;
3977    uint32_t registers = 0;
3978    bool wback;
3979    const uint32_t addr_byte_size = GetAddressByteSize();
3980    switch (encoding) {
3981    case eEncodingT1:
3982      // n = UInt(Rn); registers = '00000000':register_list; wback =
3983      // (registers<n> == '0');
3984      n = Bits32(opcode, 10, 8);
3985      registers = Bits32(opcode, 7, 0);
3986      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3987      wback = BitIsClear(registers, n);
3988      // if BitCount(registers) < 1 then UNPREDICTABLE;
3989      if (BitCount(registers) < 1)
3990        return false;
3991      break;
3992    case eEncodingT2:
3993      // if W == '1' && Rn == '1101' then SEE POP;
3994      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3995      n = Bits32(opcode, 19, 16);
3996      registers = Bits32(opcode, 15, 0);
3997      registers = registers & 0xdfff; // Make sure bit 13 is zero.
3998      wback = BitIsSet(opcode, 21);
3999
4000      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4001      // UNPREDICTABLE;
4002      if ((n == 15) || (BitCount(registers) < 2) ||
4003          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4004        return false;
4005
4006      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4007      // UNPREDICTABLE;
4008      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4009        return false;
4010
4011      // if wback && registers<n> == '1' then UNPREDICTABLE;
4012      if (wback && BitIsSet(registers, n))
4013        return false;
4014      break;
4015
4016    case eEncodingA1:
4017      n = Bits32(opcode, 19, 16);
4018      registers = Bits32(opcode, 15, 0);
4019      wback = BitIsSet(opcode, 21);
4020      if ((n == 15) || (BitCount(registers) < 1))
4021        return false;
4022      break;
4023    default:
4024      return false;
4025    }
4026
4027    int32_t offset = 0;
4028    const addr_t base_address =
4029        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4030    if (!success)
4031      return false;
4032
4033    EmulateInstruction::Context context;
4034    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4035    RegisterInfo dwarf_reg;
4036    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4037    context.SetRegisterPlusOffset(dwarf_reg, offset);
4038
4039    for (int i = 0; i < 14; ++i) {
4040      if (BitIsSet(registers, i)) {
4041        context.type = EmulateInstruction::eContextRegisterPlusOffset;
4042        context.SetRegisterPlusOffset(dwarf_reg, offset);
4043        if (wback && (n == 13)) // Pop Instruction
4044        {
4045          context.type = EmulateInstruction::eContextPopRegisterOffStack;
4046          context.SetAddress(base_address + offset);
4047        }
4048
4049        // R[i] = MemA [address, 4]; address = address + 4;
4050        uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4051                                 0, &success);
4052        if (!success)
4053          return false;
4054
4055        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4056                                   data))
4057          return false;
4058
4059        offset += addr_byte_size;
4060      }
4061    }
4062
4063    if (BitIsSet(registers, 15)) {
4064      // LoadWritePC (MemA [address, 4]);
4065      context.type = EmulateInstruction::eContextRegisterPlusOffset;
4066      context.SetRegisterPlusOffset(dwarf_reg, offset);
4067      uint32_t data =
4068          MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4069      if (!success)
4070        return false;
4071      // In ARMv5T and above, this is an interworking branch.
4072      if (!LoadWritePC(context, data))
4073        return false;
4074    }
4075
4076    if (wback && BitIsClear(registers, n)) {
4077      // R[n] = R[n] + 4 * BitCount (registers)
4078      int32_t offset = addr_byte_size * BitCount(registers);
4079      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4080      context.SetRegisterPlusOffset(dwarf_reg, offset);
4081
4082      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4083                                 base_address + offset))
4084        return false;
4085    }
4086    if (wback && BitIsSet(registers, n))
4087      // R[n] bits(32) UNKNOWN;
4088      return WriteBits32Unknown(n);
4089  }
4090  return true;
4091}
4092
4093// LDMDA loads multiple registers from consecutive memory locations using an
4094// address from a base register.
4095// The consecutive memory locations end at this address and the address just
4096// below the lowest of those locations
4097// can optionally be written back to the base register.
4098bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4099                                         const ARMEncoding encoding) {
4100#if 0
4101    // ARM pseudo code...
4102    if ConditionPassed() then
4103        EncodingSpecificOperations();
4104        address = R[n] - 4*BitCount(registers) + 4;
4105
4106        for i = 0 to 14
4107            if registers<i> == '1' then
4108                  R[i] = MemA[address,4]; address = address + 4;
4109
4110        if registers<15> == '1' then
4111            LoadWritePC(MemA[address,4]);
4112
4113        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4114        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4115#endif
4116
4117  bool success = false;
4118
4119  if (ConditionPassed(opcode)) {
4120    uint32_t n;
4121    uint32_t registers = 0;
4122    bool wback;
4123    const uint32_t addr_byte_size = GetAddressByteSize();
4124
4125    // EncodingSpecificOperations();
4126    switch (encoding) {
4127    case eEncodingA1:
4128      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4129      n = Bits32(opcode, 19, 16);
4130      registers = Bits32(opcode, 15, 0);
4131      wback = BitIsSet(opcode, 21);
4132
4133      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4134      if ((n == 15) || (BitCount(registers) < 1))
4135        return false;
4136
4137      break;
4138
4139    default:
4140      return false;
4141    }
4142    // address = R[n] - 4*BitCount(registers) + 4;
4143
4144    int32_t offset = 0;
4145    addr_t Rn = ReadCoreReg(n, &success);
4146
4147    if (!success)
4148      return false;
4149
4150    addr_t address =
4151        Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4152
4153    EmulateInstruction::Context context;
4154    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4155    RegisterInfo dwarf_reg;
4156    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4157    context.SetRegisterPlusOffset(dwarf_reg, offset);
4158
4159    // for i = 0 to 14
4160    for (int i = 0; i < 14; ++i) {
4161      // if registers<i> == '1' then
4162      if (BitIsSet(registers, i)) {
4163        // R[i] = MemA[address,4]; address = address + 4;
4164        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4165        uint32_t data =
4166            MemARead(context, address + offset, addr_byte_size, 0, &success);
4167        if (!success)
4168          return false;
4169        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4170                                   data))
4171          return false;
4172        offset += addr_byte_size;
4173      }
4174    }
4175
4176    // if registers<15> == '1' then
4177    //     LoadWritePC(MemA[address,4]);
4178    if (BitIsSet(registers, 15)) {
4179      context.SetRegisterPlusOffset(dwarf_reg, offset);
4180      uint32_t data =
4181          MemARead(context, address + offset, addr_byte_size, 0, &success);
4182      if (!success)
4183        return false;
4184      // In ARMv5T and above, this is an interworking branch.
4185      if (!LoadWritePC(context, data))
4186        return false;
4187    }
4188
4189    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4190    if (wback && BitIsClear(registers, n)) {
4191      if (!success)
4192        return false;
4193
4194      offset = (addr_byte_size * BitCount(registers)) * -1;
4195      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4196      context.SetImmediateSigned(offset);
4197      addr_t addr = Rn + offset;
4198      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4199                                 addr))
4200        return false;
4201    }
4202
4203    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4204    if (wback && BitIsSet(registers, n))
4205      return WriteBits32Unknown(n);
4206  }
4207  return true;
4208}
4209
4210// LDMDB loads multiple registers from consecutive memory locations using an
4211// address from a base register.  The
4212// consecutive memory locations end just below this address, and the address of
4213// the lowest of those locations can
4214// be optionally written back to the base register.
4215bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4216                                         const ARMEncoding encoding) {
4217#if 0
4218    // ARM pseudo code...
4219    if ConditionPassed() then
4220        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4221        address = R[n] - 4*BitCount(registers);
4222
4223        for i = 0 to 14
4224            if registers<i> == '1' then
4225                  R[i] = MemA[address,4]; address = address + 4;
4226        if registers<15> == '1' then
4227                  LoadWritePC(MemA[address,4]);
4228
4229        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4230        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4231#endif
4232
4233  bool success = false;
4234
4235  if (ConditionPassed(opcode)) {
4236    uint32_t n;
4237    uint32_t registers = 0;
4238    bool wback;
4239    const uint32_t addr_byte_size = GetAddressByteSize();
4240    switch (encoding) {
4241    case eEncodingT1:
4242      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4243      n = Bits32(opcode, 19, 16);
4244      registers = Bits32(opcode, 15, 0);
4245      registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4246      wback = BitIsSet(opcode, 21);
4247
4248      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4249      // UNPREDICTABLE;
4250      if ((n == 15) || (BitCount(registers) < 2) ||
4251          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4252        return false;
4253
4254      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4255      // UNPREDICTABLE;
4256      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4257        return false;
4258
4259      // if wback && registers<n> == '1' then UNPREDICTABLE;
4260      if (wback && BitIsSet(registers, n))
4261        return false;
4262
4263      break;
4264
4265    case eEncodingA1:
4266      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4267      n = Bits32(opcode, 19, 16);
4268      registers = Bits32(opcode, 15, 0);
4269      wback = BitIsSet(opcode, 21);
4270
4271      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4272      if ((n == 15) || (BitCount(registers) < 1))
4273        return false;
4274
4275      break;
4276
4277    default:
4278      return false;
4279    }
4280
4281    // address = R[n] - 4*BitCount(registers);
4282
4283    int32_t offset = 0;
4284    addr_t Rn =
4285        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4286
4287    if (!success)
4288      return false;
4289
4290    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4291    EmulateInstruction::Context context;
4292    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4293    RegisterInfo dwarf_reg;
4294    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4295    context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4296
4297    for (int i = 0; i < 14; ++i) {
4298      if (BitIsSet(registers, i)) {
4299        // R[i] = MemA[address,4]; address = address + 4;
4300        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4301        uint32_t data =
4302            MemARead(context, address + offset, addr_byte_size, 0, &success);
4303        if (!success)
4304          return false;
4305
4306        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4307                                   data))
4308          return false;
4309
4310        offset += addr_byte_size;
4311      }
4312    }
4313
4314    // if registers<15> == '1' then
4315    //     LoadWritePC(MemA[address,4]);
4316    if (BitIsSet(registers, 15)) {
4317      context.SetRegisterPlusOffset(dwarf_reg, offset);
4318      uint32_t data =
4319          MemARead(context, address + offset, addr_byte_size, 0, &success);
4320      if (!success)
4321        return false;
4322      // In ARMv5T and above, this is an interworking branch.
4323      if (!LoadWritePC(context, data))
4324        return false;
4325    }
4326
4327    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4328    if (wback && BitIsClear(registers, n)) {
4329      if (!success)
4330        return false;
4331
4332      offset = (addr_byte_size * BitCount(registers)) * -1;
4333      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4334      context.SetImmediateSigned(offset);
4335      addr_t addr = Rn + offset;
4336      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4337                                 addr))
4338        return false;
4339    }
4340
4341    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4342    // possible for encoding A1
4343    if (wback && BitIsSet(registers, n))
4344      return WriteBits32Unknown(n);
4345  }
4346  return true;
4347}
4348
4349// LDMIB loads multiple registers from consecutive memory locations using an
4350// address from a base register.  The
4351// consecutive memory locations start just above this address, and thea ddress
4352// of the last of those locations can
4353// optinoally be written back to the base register.
4354bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4355                                         const ARMEncoding encoding) {
4356#if 0
4357    if ConditionPassed() then
4358        EncodingSpecificOperations();
4359        address = R[n] + 4;
4360
4361        for i = 0 to 14
4362            if registers<i> == '1' then
4363                  R[i] = MemA[address,4]; address = address + 4;
4364        if registers<15> == '1' then
4365            LoadWritePC(MemA[address,4]);
4366
4367        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4368        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4369#endif
4370
4371  bool success = false;
4372
4373  if (ConditionPassed(opcode)) {
4374    uint32_t n;
4375    uint32_t registers = 0;
4376    bool wback;
4377    const uint32_t addr_byte_size = GetAddressByteSize();
4378    switch (encoding) {
4379    case eEncodingA1:
4380      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4381      n = Bits32(opcode, 19, 16);
4382      registers = Bits32(opcode, 15, 0);
4383      wback = BitIsSet(opcode, 21);
4384
4385      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4386      if ((n == 15) || (BitCount(registers) < 1))
4387        return false;
4388
4389      break;
4390    default:
4391      return false;
4392    }
4393    // address = R[n] + 4;
4394
4395    int32_t offset = 0;
4396    addr_t Rn =
4397        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4398
4399    if (!success)
4400      return false;
4401
4402    addr_t address = Rn + addr_byte_size;
4403
4404    EmulateInstruction::Context context;
4405    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4406    RegisterInfo dwarf_reg;
4407    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4408    context.SetRegisterPlusOffset(dwarf_reg, offset);
4409
4410    for (int i = 0; i < 14; ++i) {
4411      if (BitIsSet(registers, i)) {
4412        // R[i] = MemA[address,4]; address = address + 4;
4413
4414        context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4415        uint32_t data =
4416            MemARead(context, address + offset, addr_byte_size, 0, &success);
4417        if (!success)
4418          return false;
4419
4420        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4421                                   data))
4422          return false;
4423
4424        offset += addr_byte_size;
4425      }
4426    }
4427
4428    // if registers<15> == '1' then
4429    //     LoadWritePC(MemA[address,4]);
4430    if (BitIsSet(registers, 15)) {
4431      context.SetRegisterPlusOffset(dwarf_reg, offset);
4432      uint32_t data =
4433          MemARead(context, address + offset, addr_byte_size, 0, &success);
4434      if (!success)
4435        return false;
4436      // In ARMv5T and above, this is an interworking branch.
4437      if (!LoadWritePC(context, data))
4438        return false;
4439    }
4440
4441    // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4442    if (wback && BitIsClear(registers, n)) {
4443      if (!success)
4444        return false;
4445
4446      offset = addr_byte_size * BitCount(registers);
4447      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4448      context.SetImmediateSigned(offset);
4449      addr_t addr = Rn + offset;
4450      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4451                                 addr))
4452        return false;
4453    }
4454
4455    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4456    // possible for encoding A1
4457    if (wback && BitIsSet(registers, n))
4458      return WriteBits32Unknown(n);
4459  }
4460  return true;
4461}
4462
4463// Load Register (immediate) calculates an address from a base register value
4464// and
4465// an immediate offset, loads a word from memory, and writes to a register.
4466// LDR (immediate, Thumb)
4467bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4468                                              const ARMEncoding encoding) {
4469#if 0
4470    // ARM pseudo code...
4471    if (ConditionPassed())
4472    {
4473        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4474        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4475        address = if index then offset_addr else R[n];
4476        data = MemU[address,4];
4477        if wback then R[n] = offset_addr;
4478        if t == 15 then
4479            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4480        elsif UnalignedSupport() || address<1:0> = '00' then
4481            R[t] = data;
4482        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4483    }
4484#endif
4485
4486  bool success = false;
4487
4488  if (ConditionPassed(opcode)) {
4489    uint32_t Rt;        // the destination register
4490    uint32_t Rn;        // the base register
4491    uint32_t imm32;     // the immediate offset used to form the address
4492    addr_t offset_addr; // the offset address
4493    addr_t address;     // the calculated address
4494    uint32_t data;      // the literal data value from memory load
4495    bool add, index, wback;
4496    switch (encoding) {
4497    case eEncodingT1:
4498      Rt = Bits32(opcode, 2, 0);
4499      Rn = Bits32(opcode, 5, 3);
4500      imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4501      // index = TRUE; add = TRUE; wback = FALSE
4502      add = true;
4503      index = true;
4504      wback = false;
4505
4506      break;
4507
4508    case eEncodingT2:
4509      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4510      Rt = Bits32(opcode, 10, 8);
4511      Rn = 13;
4512      imm32 = Bits32(opcode, 7, 0) << 2;
4513
4514      // index = TRUE; add = TRUE; wback = FALSE;
4515      index = true;
4516      add = true;
4517      wback = false;
4518
4519      break;
4520
4521    case eEncodingT3:
4522      // if Rn == '1111' then SEE LDR (literal);
4523      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4524      Rt = Bits32(opcode, 15, 12);
4525      Rn = Bits32(opcode, 19, 16);
4526      imm32 = Bits32(opcode, 11, 0);
4527
4528      // index = TRUE; add = TRUE; wback = FALSE;
4529      index = true;
4530      add = true;
4531      wback = false;
4532
4533      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4534      if ((Rt == 15) && InITBlock() && !LastInITBlock())
4535        return false;
4536
4537      break;
4538
4539    case eEncodingT4:
4540      // if Rn == '1111' then SEE LDR (literal);
4541      // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4542      // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4543      // '00000100' then SEE POP;
4544      // if P == '0' && W == '0' then UNDEFINED;
4545      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4546        return false;
4547
4548      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4549      Rt = Bits32(opcode, 15, 12);
4550      Rn = Bits32(opcode, 19, 16);
4551      imm32 = Bits32(opcode, 7, 0);
4552
4553      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4554      index = BitIsSet(opcode, 10);
4555      add = BitIsSet(opcode, 9);
4556      wback = BitIsSet(opcode, 8);
4557
4558      // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4559      // then UNPREDICTABLE;
4560      if ((wback && (Rn == Rt)) ||
4561          ((Rt == 15) && InITBlock() && !LastInITBlock()))
4562        return false;
4563
4564      break;
4565
4566    default:
4567      return false;
4568    }
4569    uint32_t base = ReadCoreReg(Rn, &success);
4570    if (!success)
4571      return false;
4572    if (add)
4573      offset_addr = base + imm32;
4574    else
4575      offset_addr = base - imm32;
4576
4577    address = (index ? offset_addr : base);
4578
4579    RegisterInfo base_reg;
4580    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4581    if (wback) {
4582      EmulateInstruction::Context ctx;
4583      if (Rn == 13) {
4584        ctx.type = eContextAdjustStackPointer;
4585        ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4586      } else if (Rn == GetFramePointerRegisterNumber()) {
4587        ctx.type = eContextSetFramePointer;
4588        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4589      } else {
4590        ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4591        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4592      }
4593
4594      if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4595                                 offset_addr))
4596        return false;
4597    }
4598
4599    // Prepare to write to the Rt register.
4600    EmulateInstruction::Context context;
4601    context.type = EmulateInstruction::eContextRegisterLoad;
4602    context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4603
4604    // Read memory from the address.
4605    data = MemURead(context, address, 4, 0, &success);
4606    if (!success)
4607      return false;
4608
4609    if (Rt == 15) {
4610      if (Bits32(address, 1, 0) == 0) {
4611        if (!LoadWritePC(context, data))
4612          return false;
4613      } else
4614        return false;
4615    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4616      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4617                                 data))
4618        return false;
4619    } else
4620      WriteBits32Unknown(Rt);
4621  }
4622  return true;
4623}
4624
4625// STM (Store Multiple Increment After) stores multiple registers to consecutive
4626// memory locations using an address
4627// from a base register.  The consecutive memory locations start at this
4628// address, and the address just above the last
4629// of those locations can optionally be written back to the base register.
4630bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4631                                       const ARMEncoding encoding) {
4632#if 0
4633    if ConditionPassed() then
4634        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4635        address = R[n];
4636
4637        for i = 0 to 14
4638            if registers<i> == '1' then
4639                if i == n && wback && i != LowestSetBit(registers) then
4640                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4641                else
4642                    MemA[address,4] = R[i];
4643                address = address + 4;
4644
4645        if registers<15> == '1' then // Only possible for encoding A1
4646            MemA[address,4] = PCStoreValue();
4647        if wback then R[n] = R[n] + 4*BitCount(registers);
4648#endif
4649
4650  bool success = false;
4651
4652  if (ConditionPassed(opcode)) {
4653    uint32_t n;
4654    uint32_t registers = 0;
4655    bool wback;
4656    const uint32_t addr_byte_size = GetAddressByteSize();
4657
4658    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4659    switch (encoding) {
4660    case eEncodingT1:
4661      // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4662      n = Bits32(opcode, 10, 8);
4663      registers = Bits32(opcode, 7, 0);
4664      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4665      wback = true;
4666
4667      // if BitCount(registers) < 1 then UNPREDICTABLE;
4668      if (BitCount(registers) < 1)
4669        return false;
4670
4671      break;
4672
4673    case eEncodingT2:
4674      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4675      n = Bits32(opcode, 19, 16);
4676      registers = Bits32(opcode, 15, 0);
4677      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4678      wback = BitIsSet(opcode, 21);
4679
4680      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4681      if ((n == 15) || (BitCount(registers) < 2))
4682        return false;
4683
4684      // if wback && registers<n> == '1' then UNPREDICTABLE;
4685      if (wback && BitIsSet(registers, n))
4686        return false;
4687
4688      break;
4689
4690    case eEncodingA1:
4691      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4692      n = Bits32(opcode, 19, 16);
4693      registers = Bits32(opcode, 15, 0);
4694      wback = BitIsSet(opcode, 21);
4695
4696      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4697      if ((n == 15) || (BitCount(registers) < 1))
4698        return false;
4699
4700      break;
4701
4702    default:
4703      return false;
4704    }
4705
4706    // address = R[n];
4707    int32_t offset = 0;
4708    const addr_t address =
4709        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4710    if (!success)
4711      return false;
4712
4713    EmulateInstruction::Context context;
4714    context.type = EmulateInstruction::eContextRegisterStore;
4715    RegisterInfo base_reg;
4716    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4717
4718    // for i = 0 to 14
4719    uint32_t lowest_set_bit = 14;
4720    for (uint32_t i = 0; i < 14; ++i) {
4721      // if registers<i> == '1' then
4722      if (BitIsSet(registers, i)) {
4723        if (i < lowest_set_bit)
4724          lowest_set_bit = i;
4725        // if i == n && wback && i != LowestSetBit(registers) then
4726        if ((i == n) && wback && (i != lowest_set_bit))
4727          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4728          // T1 and A1
4729          WriteBits32UnknownToMemory(address + offset);
4730        else {
4731          // MemA[address,4] = R[i];
4732          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4733                                               0, &success);
4734          if (!success)
4735            return false;
4736
4737          RegisterInfo data_reg;
4738          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4739          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4740          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4741            return false;
4742        }
4743
4744        // address = address + 4;
4745        offset += addr_byte_size;
4746      }
4747    }
4748
4749    // if registers<15> == '1' then // Only possible for encoding A1
4750    //     MemA[address,4] = PCStoreValue();
4751    if (BitIsSet(registers, 15)) {
4752      RegisterInfo pc_reg;
4753      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4754      context.SetRegisterPlusOffset(pc_reg, 8);
4755      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4756      if (!success)
4757        return false;
4758
4759      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4760        return false;
4761    }
4762
4763    // if wback then R[n] = R[n] + 4*BitCount(registers);
4764    if (wback) {
4765      offset = addr_byte_size * BitCount(registers);
4766      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4767      context.SetImmediateSigned(offset);
4768      addr_t data = address + offset;
4769      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4770                                 data))
4771        return false;
4772    }
4773  }
4774  return true;
4775}
4776
4777// STMDA (Store Multiple Decrement After) stores multiple registers to
4778// consecutive memory locations using an address
4779// from a base register.  The consecutive memory locations end at this address,
4780// and the address just below the lowest
4781// of those locations can optionally be written back to the base register.
4782bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4783                                         const ARMEncoding encoding) {
4784#if 0
4785    if ConditionPassed() then
4786        EncodingSpecificOperations();
4787        address = R[n] - 4*BitCount(registers) + 4;
4788
4789        for i = 0 to 14
4790            if registers<i> == '1' then
4791                if i == n && wback && i != LowestSetBit(registers) then
4792                    MemA[address,4] = bits(32) UNKNOWN;
4793                else
4794                    MemA[address,4] = R[i];
4795                address = address + 4;
4796
4797        if registers<15> == '1' then
4798            MemA[address,4] = PCStoreValue();
4799
4800        if wback then R[n] = R[n] - 4*BitCount(registers);
4801#endif
4802
4803  bool success = false;
4804
4805  if (ConditionPassed(opcode)) {
4806    uint32_t n;
4807    uint32_t registers = 0;
4808    bool wback;
4809    const uint32_t addr_byte_size = GetAddressByteSize();
4810
4811    // EncodingSpecificOperations();
4812    switch (encoding) {
4813    case eEncodingA1:
4814      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4815      n = Bits32(opcode, 19, 16);
4816      registers = Bits32(opcode, 15, 0);
4817      wback = BitIsSet(opcode, 21);
4818
4819      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4820      if ((n == 15) || (BitCount(registers) < 1))
4821        return false;
4822      break;
4823    default:
4824      return false;
4825    }
4826
4827    // address = R[n] - 4*BitCount(registers) + 4;
4828    int32_t offset = 0;
4829    addr_t Rn = ReadCoreReg(n, &success);
4830    if (!success)
4831      return false;
4832
4833    addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4834
4835    EmulateInstruction::Context context;
4836    context.type = EmulateInstruction::eContextRegisterStore;
4837    RegisterInfo base_reg;
4838    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4839
4840    // for i = 0 to 14
4841    uint32_t lowest_bit_set = 14;
4842    for (uint32_t i = 0; i < 14; ++i) {
4843      // if registers<i> == '1' then
4844      if (BitIsSet(registers, i)) {
4845        if (i < lowest_bit_set)
4846          lowest_bit_set = i;
4847        // if i == n && wback && i != LowestSetBit(registers) then
4848        if ((i == n) && wback && (i != lowest_bit_set))
4849          // MemA[address,4] = bits(32) UNKNOWN;
4850          WriteBits32UnknownToMemory(address + offset);
4851        else {
4852          // MemA[address,4] = R[i];
4853          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4854                                               0, &success);
4855          if (!success)
4856            return false;
4857
4858          RegisterInfo data_reg;
4859          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4860          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4861                                                  Rn - (address + offset));
4862          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4863            return false;
4864        }
4865
4866        // address = address + 4;
4867        offset += addr_byte_size;
4868      }
4869    }
4870
4871    // if registers<15> == '1' then
4872    //    MemA[address,4] = PCStoreValue();
4873    if (BitIsSet(registers, 15)) {
4874      RegisterInfo pc_reg;
4875      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4876      context.SetRegisterPlusOffset(pc_reg, 8);
4877      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4878      if (!success)
4879        return false;
4880
4881      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4882        return false;
4883    }
4884
4885    // if wback then R[n] = R[n] - 4*BitCount(registers);
4886    if (wback) {
4887      offset = (addr_byte_size * BitCount(registers)) * -1;
4888      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4889      context.SetImmediateSigned(offset);
4890      addr_t data = Rn + offset;
4891      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4892                                 data))
4893        return false;
4894    }
4895  }
4896  return true;
4897}
4898
4899// STMDB (Store Multiple Decrement Before) stores multiple registers to
4900// consecutive memory locations using an address
4901// from a base register.  The consecutive memory locations end just below this
4902// address, and the address of the first of
4903// those locations can optionally be written back to the base register.
4904bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4905                                         const ARMEncoding encoding) {
4906#if 0
4907    if ConditionPassed() then
4908        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4909        address = R[n] - 4*BitCount(registers);
4910
4911        for i = 0 to 14
4912            if registers<i> == '1' then
4913                if i == n && wback && i != LowestSetBit(registers) then
4914                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4915                else
4916                    MemA[address,4] = R[i];
4917                address = address + 4;
4918
4919        if registers<15> == '1' then // Only possible for encoding A1
4920            MemA[address,4] = PCStoreValue();
4921
4922        if wback then R[n] = R[n] - 4*BitCount(registers);
4923#endif
4924
4925  bool success = false;
4926
4927  if (ConditionPassed(opcode)) {
4928    uint32_t n;
4929    uint32_t registers = 0;
4930    bool wback;
4931    const uint32_t addr_byte_size = GetAddressByteSize();
4932
4933    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4934    switch (encoding) {
4935    case eEncodingT1:
4936      // if W == '1' && Rn == '1101' then SEE PUSH;
4937      if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4938        // See PUSH
4939      }
4940      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4941      n = Bits32(opcode, 19, 16);
4942      registers = Bits32(opcode, 15, 0);
4943      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4944      wback = BitIsSet(opcode, 21);
4945      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4946      if ((n == 15) || BitCount(registers) < 2)
4947        return false;
4948      // if wback && registers<n> == '1' then UNPREDICTABLE;
4949      if (wback && BitIsSet(registers, n))
4950        return false;
4951      break;
4952
4953    case eEncodingA1:
4954      // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4955      // PUSH;
4956      if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4957          BitCount(Bits32(opcode, 15, 0)) >= 2) {
4958        // See Push
4959      }
4960      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4961      n = Bits32(opcode, 19, 16);
4962      registers = Bits32(opcode, 15, 0);
4963      wback = BitIsSet(opcode, 21);
4964      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4965      if ((n == 15) || BitCount(registers) < 1)
4966        return false;
4967      break;
4968
4969    default:
4970      return false;
4971    }
4972
4973    // address = R[n] - 4*BitCount(registers);
4974
4975    int32_t offset = 0;
4976    addr_t Rn =
4977        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4978    if (!success)
4979      return false;
4980
4981    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4982
4983    EmulateInstruction::Context context;
4984    context.type = EmulateInstruction::eContextRegisterStore;
4985    RegisterInfo base_reg;
4986    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4987
4988    // for i = 0 to 14
4989    uint32_t lowest_set_bit = 14;
4990    for (uint32_t i = 0; i < 14; ++i) {
4991      // if registers<i> == '1' then
4992      if (BitIsSet(registers, i)) {
4993        if (i < lowest_set_bit)
4994          lowest_set_bit = i;
4995        // if i == n && wback && i != LowestSetBit(registers) then
4996        if ((i == n) && wback && (i != lowest_set_bit))
4997          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4998          // A1
4999          WriteBits32UnknownToMemory(address + offset);
5000        else {
5001          // MemA[address,4] = R[i];
5002          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5003                                               0, &success);
5004          if (!success)
5005            return false;
5006
5007          RegisterInfo data_reg;
5008          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5009          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5010                                                  Rn - (address + offset));
5011          if (!MemAWrite(context, address + offset, data, addr_byte_size))
5012            return false;
5013        }
5014
5015        // address = address + 4;
5016        offset += addr_byte_size;
5017      }
5018    }
5019
5020    // if registers<15> == '1' then // Only possible for encoding A1
5021    //     MemA[address,4] = PCStoreValue();
5022    if (BitIsSet(registers, 15)) {
5023      RegisterInfo pc_reg;
5024      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5025      context.SetRegisterPlusOffset(pc_reg, 8);
5026      const uint32_t pc = ReadCoreReg(PC_REG, &success);
5027      if (!success)
5028        return false;
5029
5030      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5031        return false;
5032    }
5033
5034    // if wback then R[n] = R[n] - 4*BitCount(registers);
5035    if (wback) {
5036      offset = (addr_byte_size * BitCount(registers)) * -1;
5037      context.type = EmulateInstruction::eContextAdjustBaseRegister;
5038      context.SetImmediateSigned(offset);
5039      addr_t data = Rn + offset;
5040      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5041                                 data))
5042        return false;
5043    }
5044  }
5045  return true;
5046}
5047
5048// STMIB (Store Multiple Increment Before) stores multiple registers to
5049// consecutive memory locations using an address
5050// from a base register.  The consecutive memory locations start just above this
5051// address, and the address of the last
5052// of those locations can optionally be written back to the base register.
5053bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5054                                         const ARMEncoding encoding) {
5055#if 0
5056    if ConditionPassed() then
5057        EncodingSpecificOperations();
5058        address = R[n] + 4;
5059
5060        for i = 0 to 14
5061            if registers<i> == '1' then
5062                if i == n && wback && i != LowestSetBit(registers) then
5063                    MemA[address,4] = bits(32) UNKNOWN;
5064                else
5065                    MemA[address,4] = R[i];
5066                address = address + 4;
5067
5068        if registers<15> == '1' then
5069            MemA[address,4] = PCStoreValue();
5070
5071        if wback then R[n] = R[n] + 4*BitCount(registers);
5072#endif
5073
5074  bool success = false;
5075
5076  if (ConditionPassed(opcode)) {
5077    uint32_t n;
5078    uint32_t registers = 0;
5079    bool wback;
5080    const uint32_t addr_byte_size = GetAddressByteSize();
5081
5082    // EncodingSpecificOperations();
5083    switch (encoding) {
5084    case eEncodingA1:
5085      // n = UInt(Rn); registers = register_list; wback = (W == '1');
5086      n = Bits32(opcode, 19, 16);
5087      registers = Bits32(opcode, 15, 0);
5088      wback = BitIsSet(opcode, 21);
5089
5090      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5091      if ((n == 15) && (BitCount(registers) < 1))
5092        return false;
5093      break;
5094    default:
5095      return false;
5096    }
5097    // address = R[n] + 4;
5098
5099    int32_t offset = 0;
5100    addr_t Rn = ReadCoreReg(n, &success);
5101    if (!success)
5102      return false;
5103
5104    addr_t address = Rn + addr_byte_size;
5105
5106    EmulateInstruction::Context context;
5107    context.type = EmulateInstruction::eContextRegisterStore;
5108    RegisterInfo base_reg;
5109    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5110
5111    uint32_t lowest_set_bit = 14;
5112    // for i = 0 to 14
5113    for (uint32_t i = 0; i < 14; ++i) {
5114      // if registers<i> == '1' then
5115      if (BitIsSet(registers, i)) {
5116        if (i < lowest_set_bit)
5117          lowest_set_bit = i;
5118        // if i == n && wback && i != LowestSetBit(registers) then
5119        if ((i == n) && wback && (i != lowest_set_bit))
5120          // MemA[address,4] = bits(32) UNKNOWN;
5121          WriteBits32UnknownToMemory(address + offset);
5122        // else
5123        else {
5124          // MemA[address,4] = R[i];
5125          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5126                                               0, &success);
5127          if (!success)
5128            return false;
5129
5130          RegisterInfo data_reg;
5131          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5132          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5133                                                  offset + addr_byte_size);
5134          if (!MemAWrite(context, address + offset, data, addr_byte_size))
5135            return false;
5136        }
5137
5138        // address = address + 4;
5139        offset += addr_byte_size;
5140      }
5141    }
5142
5143    // if registers<15> == '1' then
5144    // MemA[address,4] = PCStoreValue();
5145    if (BitIsSet(registers, 15)) {
5146      RegisterInfo pc_reg;
5147      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5148      context.SetRegisterPlusOffset(pc_reg, 8);
5149      const uint32_t pc = ReadCoreReg(PC_REG, &success);
5150      if (!success)
5151        return false;
5152
5153      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5154        return false;
5155    }
5156
5157    // if wback then R[n] = R[n] + 4*BitCount(registers);
5158    if (wback) {
5159      offset = addr_byte_size * BitCount(registers);
5160      context.type = EmulateInstruction::eContextAdjustBaseRegister;
5161      context.SetImmediateSigned(offset);
5162      addr_t data = Rn + offset;
5163      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5164                                 data))
5165        return false;
5166    }
5167  }
5168  return true;
5169}
5170
5171// STR (store immediate) calculates an address from a base register value and an
5172// immediate offset, and stores a word
5173// from a register to memory.  It can use offset, post-indexed, or pre-indexed
5174// addressing.
5175bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5176                                            const ARMEncoding encoding) {
5177#if 0
5178    if ConditionPassed() then
5179        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5180        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5181        address = if index then offset_addr else R[n];
5182        if UnalignedSupport() || address<1:0> == '00' then
5183            MemU[address,4] = R[t];
5184        else // Can only occur before ARMv7
5185            MemU[address,4] = bits(32) UNKNOWN;
5186        if wback then R[n] = offset_addr;
5187#endif
5188
5189  bool success = false;
5190
5191  if (ConditionPassed(opcode)) {
5192    const uint32_t addr_byte_size = GetAddressByteSize();
5193
5194    uint32_t t;
5195    uint32_t n;
5196    uint32_t imm32;
5197    bool index;
5198    bool add;
5199    bool wback;
5200    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5201    switch (encoding) {
5202    case eEncodingT1:
5203      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5204      t = Bits32(opcode, 2, 0);
5205      n = Bits32(opcode, 5, 3);
5206      imm32 = Bits32(opcode, 10, 6) << 2;
5207
5208      // index = TRUE; add = TRUE; wback = FALSE;
5209      index = true;
5210      add = false;
5211      wback = false;
5212      break;
5213
5214    case eEncodingT2:
5215      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5216      t = Bits32(opcode, 10, 8);
5217      n = 13;
5218      imm32 = Bits32(opcode, 7, 0) << 2;
5219
5220      // index = TRUE; add = TRUE; wback = FALSE;
5221      index = true;
5222      add = true;
5223      wback = false;
5224      break;
5225
5226    case eEncodingT3:
5227      // if Rn == '1111' then UNDEFINED;
5228      if (Bits32(opcode, 19, 16) == 15)
5229        return false;
5230
5231      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5232      t = Bits32(opcode, 15, 12);
5233      n = Bits32(opcode, 19, 16);
5234      imm32 = Bits32(opcode, 11, 0);
5235
5236      // index = TRUE; add = TRUE; wback = FALSE;
5237      index = true;
5238      add = true;
5239      wback = false;
5240
5241      // if t == 15 then UNPREDICTABLE;
5242      if (t == 15)
5243        return false;
5244      break;
5245
5246    case eEncodingT4:
5247      // if P == '1' && U == '1' && W == '0' then SEE STRT;
5248      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5249      // '00000100' then SEE PUSH;
5250      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5251      if ((Bits32(opcode, 19, 16) == 15) ||
5252          (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5253        return false;
5254
5255      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5256      t = Bits32(opcode, 15, 12);
5257      n = Bits32(opcode, 19, 16);
5258      imm32 = Bits32(opcode, 7, 0);
5259
5260      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5261      index = BitIsSet(opcode, 10);
5262      add = BitIsSet(opcode, 9);
5263      wback = BitIsSet(opcode, 8);
5264
5265      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5266      if ((t == 15) || (wback && (n == t)))
5267        return false;
5268      break;
5269
5270    default:
5271      return false;
5272    }
5273
5274    addr_t offset_addr;
5275    addr_t address;
5276
5277    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5278    uint32_t base_address = ReadCoreReg(n, &success);
5279    if (!success)
5280      return false;
5281
5282    if (add)
5283      offset_addr = base_address + imm32;
5284    else
5285      offset_addr = base_address - imm32;
5286
5287    // address = if index then offset_addr else R[n];
5288    if (index)
5289      address = offset_addr;
5290    else
5291      address = base_address;
5292
5293    EmulateInstruction::Context context;
5294    if (n == 13)
5295      context.type = eContextPushRegisterOnStack;
5296    else
5297      context.type = eContextRegisterStore;
5298
5299    RegisterInfo base_reg;
5300    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5301
5302    // if UnalignedSupport() || address<1:0> == '00' then
5303    if (UnalignedSupport() ||
5304        (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5305      // MemU[address,4] = R[t];
5306      uint32_t data =
5307          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5308      if (!success)
5309        return false;
5310
5311      RegisterInfo data_reg;
5312      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5313      int32_t offset = address - base_address;
5314      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5315      if (!MemUWrite(context, address, data, addr_byte_size))
5316        return false;
5317    } else {
5318      // MemU[address,4] = bits(32) UNKNOWN;
5319      WriteBits32UnknownToMemory(address);
5320    }
5321
5322    // if wback then R[n] = offset_addr;
5323    if (wback) {
5324      if (n == 13)
5325        context.type = eContextAdjustStackPointer;
5326      else
5327        context.type = eContextAdjustBaseRegister;
5328      context.SetAddress(offset_addr);
5329
5330      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5331                                 offset_addr))
5332        return false;
5333    }
5334  }
5335  return true;
5336}
5337
5338// STR (Store Register) calculates an address from a base register value and an
5339// offset register value, stores a
5340// word from a register to memory.   The offset register value can optionally be
5341// shifted.
5342bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5343                                               const ARMEncoding encoding) {
5344#if 0
5345    if ConditionPassed() then
5346        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5347        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5348        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5349        address = if index then offset_addr else R[n];
5350        if t == 15 then // Only possible for encoding A1
5351            data = PCStoreValue();
5352        else
5353            data = R[t];
5354        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5355            MemU[address,4] = data;
5356        else // Can only occur before ARMv7
5357            MemU[address,4] = bits(32) UNKNOWN;
5358        if wback then R[n] = offset_addr;
5359#endif
5360
5361  bool success = false;
5362
5363  if (ConditionPassed(opcode)) {
5364    const uint32_t addr_byte_size = GetAddressByteSize();
5365
5366    uint32_t t;
5367    uint32_t n;
5368    uint32_t m;
5369    ARM_ShifterType shift_t;
5370    uint32_t shift_n;
5371    bool index;
5372    bool add;
5373    bool wback;
5374
5375    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5376    switch (encoding) {
5377    case eEncodingT1:
5378      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5379      // in ThumbEE";
5380      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5381      t = Bits32(opcode, 2, 0);
5382      n = Bits32(opcode, 5, 3);
5383      m = Bits32(opcode, 8, 6);
5384
5385      // index = TRUE; add = TRUE; wback = FALSE;
5386      index = true;
5387      add = true;
5388      wback = false;
5389
5390      // (shift_t, shift_n) = (SRType_LSL, 0);
5391      shift_t = SRType_LSL;
5392      shift_n = 0;
5393      break;
5394
5395    case eEncodingT2:
5396      // if Rn == '1111' then UNDEFINED;
5397      if (Bits32(opcode, 19, 16) == 15)
5398        return false;
5399
5400      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5401      t = Bits32(opcode, 15, 12);
5402      n = Bits32(opcode, 19, 16);
5403      m = Bits32(opcode, 3, 0);
5404
5405      // index = TRUE; add = TRUE; wback = FALSE;
5406      index = true;
5407      add = true;
5408      wback = false;
5409
5410      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5411      shift_t = SRType_LSL;
5412      shift_n = Bits32(opcode, 5, 4);
5413
5414      // if t == 15 || BadReg(m) then UNPREDICTABLE;
5415      if ((t == 15) || (BadReg(m)))
5416        return false;
5417      break;
5418
5419    case eEncodingA1: {
5420      // if P == '0' && W == '1' then SEE STRT;
5421      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5422      t = Bits32(opcode, 15, 12);
5423      n = Bits32(opcode, 19, 16);
5424      m = Bits32(opcode, 3, 0);
5425
5426      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
5427      // (W == '1');
5428      index = BitIsSet(opcode, 24);
5429      add = BitIsSet(opcode, 23);
5430      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5431
5432      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5433      uint32_t typ = Bits32(opcode, 6, 5);
5434      uint32_t imm5 = Bits32(opcode, 11, 7);
5435      shift_n = DecodeImmShift(typ, imm5, shift_t);
5436
5437      // if m == 15 then UNPREDICTABLE;
5438      if (m == 15)
5439        return false;
5440
5441      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5442      if (wback && ((n == 15) || (n == t)))
5443        return false;
5444
5445      break;
5446    }
5447    default:
5448      return false;
5449    }
5450
5451    addr_t offset_addr;
5452    addr_t address;
5453    int32_t offset = 0;
5454
5455    addr_t base_address =
5456        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5457    if (!success)
5458      return false;
5459
5460    uint32_t Rm_data =
5461        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5462    if (!success)
5463      return false;
5464
5465    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5466    offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5467    if (!success)
5468      return false;
5469
5470    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5471    if (add)
5472      offset_addr = base_address + offset;
5473    else
5474      offset_addr = base_address - offset;
5475
5476    // address = if index then offset_addr else R[n];
5477    if (index)
5478      address = offset_addr;
5479    else
5480      address = base_address;
5481
5482    uint32_t data;
5483    // if t == 15 then // Only possible for encoding A1
5484    if (t == 15)
5485      // data = PCStoreValue();
5486      data = ReadCoreReg(PC_REG, &success);
5487    else
5488      // data = R[t];
5489      data =
5490          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5491
5492    if (!success)
5493      return false;
5494
5495    EmulateInstruction::Context context;
5496    context.type = eContextRegisterStore;
5497
5498    // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5499    // InstrSet_ARM then
5500    if (UnalignedSupport() ||
5501        (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5502        CurrentInstrSet() == eModeARM) {
5503      // MemU[address,4] = data;
5504
5505      RegisterInfo base_reg;
5506      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5507
5508      RegisterInfo data_reg;
5509      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5510
5511      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5512                                              address - base_address);
5513      if (!MemUWrite(context, address, data, addr_byte_size))
5514        return false;
5515
5516    } else
5517      // MemU[address,4] = bits(32) UNKNOWN;
5518      WriteBits32UnknownToMemory(address);
5519
5520    // if wback then R[n] = offset_addr;
5521    if (wback) {
5522      context.type = eContextRegisterLoad;
5523      context.SetAddress(offset_addr);
5524      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5525                                 offset_addr))
5526        return false;
5527    }
5528  }
5529  return true;
5530}
5531
5532bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5533                                             const ARMEncoding encoding) {
5534#if 0
5535    if ConditionPassed() then
5536        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5537        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5538        address = if index then offset_addr else R[n];
5539        MemU[address,1] = R[t]<7:0>;
5540        if wback then R[n] = offset_addr;
5541#endif
5542
5543  bool success = false;
5544
5545  if (ConditionPassed(opcode)) {
5546    uint32_t t;
5547    uint32_t n;
5548    uint32_t imm32;
5549    bool index;
5550    bool add;
5551    bool wback;
5552    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5553    switch (encoding) {
5554    case eEncodingT1:
5555      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5556      t = Bits32(opcode, 2, 0);
5557      n = Bits32(opcode, 5, 3);
5558      imm32 = Bits32(opcode, 10, 6);
5559
5560      // index = TRUE; add = TRUE; wback = FALSE;
5561      index = true;
5562      add = true;
5563      wback = false;
5564      break;
5565
5566    case eEncodingT2:
5567      // if Rn == '1111' then UNDEFINED;
5568      if (Bits32(opcode, 19, 16) == 15)
5569        return false;
5570
5571      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5572      t = Bits32(opcode, 15, 12);
5573      n = Bits32(opcode, 19, 16);
5574      imm32 = Bits32(opcode, 11, 0);
5575
5576      // index = TRUE; add = TRUE; wback = FALSE;
5577      index = true;
5578      add = true;
5579      wback = false;
5580
5581      // if BadReg(t) then UNPREDICTABLE;
5582      if (BadReg(t))
5583        return false;
5584      break;
5585
5586    case eEncodingT3:
5587      // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5588      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5589      if (Bits32(opcode, 19, 16) == 15)
5590        return false;
5591
5592      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5593      t = Bits32(opcode, 15, 12);
5594      n = Bits32(opcode, 19, 16);
5595      imm32 = Bits32(opcode, 7, 0);
5596
5597      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5598      index = BitIsSet(opcode, 10);
5599      add = BitIsSet(opcode, 9);
5600      wback = BitIsSet(opcode, 8);
5601
5602      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5603      if ((BadReg(t)) || (wback && (n == t)))
5604        return false;
5605      break;
5606
5607    default:
5608      return false;
5609    }
5610
5611    addr_t offset_addr;
5612    addr_t address;
5613    addr_t base_address =
5614        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5615    if (!success)
5616      return false;
5617
5618    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5619    if (add)
5620      offset_addr = base_address + imm32;
5621    else
5622      offset_addr = base_address - imm32;
5623
5624    // address = if index then offset_addr else R[n];
5625    if (index)
5626      address = offset_addr;
5627    else
5628      address = base_address;
5629
5630    // MemU[address,1] = R[t]<7:0>
5631    RegisterInfo base_reg;
5632    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5633
5634    RegisterInfo data_reg;
5635    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5636
5637    EmulateInstruction::Context context;
5638    context.type = eContextRegisterStore;
5639    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5640                                            address - base_address);
5641
5642    uint32_t data =
5643        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5644    if (!success)
5645      return false;
5646
5647    data = Bits32(data, 7, 0);
5648
5649    if (!MemUWrite(context, address, data, 1))
5650      return false;
5651
5652    // if wback then R[n] = offset_addr;
5653    if (wback) {
5654      context.type = eContextRegisterLoad;
5655      context.SetAddress(offset_addr);
5656      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5657                                 offset_addr))
5658        return false;
5659    }
5660  }
5661
5662  return true;
5663}
5664
5665// STRH (register) calculates an address from a base register value and an
5666// offset register value, and stores a
5667// halfword from a register to memory.  The offset register value can be shifted
5668// left by 0, 1, 2, or 3 bits.
5669bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5670                                                const ARMEncoding encoding) {
5671#if 0
5672    if ConditionPassed() then
5673        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5674        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5675        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5676        address = if index then offset_addr else R[n];
5677        if UnalignedSupport() || address<0> == '0' then
5678            MemU[address,2] = R[t]<15:0>;
5679        else // Can only occur before ARMv7
5680            MemU[address,2] = bits(16) UNKNOWN;
5681        if wback then R[n] = offset_addr;
5682#endif
5683
5684  bool success = false;
5685
5686  if (ConditionPassed(opcode)) {
5687    uint32_t t;
5688    uint32_t n;
5689    uint32_t m;
5690    bool index;
5691    bool add;
5692    bool wback;
5693    ARM_ShifterType shift_t;
5694    uint32_t shift_n;
5695
5696    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5697    switch (encoding) {
5698    case eEncodingT1:
5699      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5700      // in ThumbEE";
5701      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5702      t = Bits32(opcode, 2, 0);
5703      n = Bits32(opcode, 5, 3);
5704      m = Bits32(opcode, 8, 6);
5705
5706      // index = TRUE; add = TRUE; wback = FALSE;
5707      index = true;
5708      add = true;
5709      wback = false;
5710
5711      // (shift_t, shift_n) = (SRType_LSL, 0);
5712      shift_t = SRType_LSL;
5713      shift_n = 0;
5714
5715      break;
5716
5717    case eEncodingT2:
5718      // if Rn == '1111' then UNDEFINED;
5719      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5720      t = Bits32(opcode, 15, 12);
5721      n = Bits32(opcode, 19, 16);
5722      m = Bits32(opcode, 3, 0);
5723      if (n == 15)
5724        return false;
5725
5726      // index = TRUE; add = TRUE; wback = FALSE;
5727      index = true;
5728      add = true;
5729      wback = false;
5730
5731      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5732      shift_t = SRType_LSL;
5733      shift_n = Bits32(opcode, 5, 4);
5734
5735      // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5736      if (BadReg(t) || BadReg(m))
5737        return false;
5738
5739      break;
5740
5741    case eEncodingA1:
5742      // if P == '0' && W == '1' then SEE STRHT;
5743      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5744      t = Bits32(opcode, 15, 12);
5745      n = Bits32(opcode, 19, 16);
5746      m = Bits32(opcode, 3, 0);
5747
5748      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
5749      // (W == '1');
5750      index = BitIsSet(opcode, 24);
5751      add = BitIsSet(opcode, 23);
5752      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5753
5754      // (shift_t, shift_n) = (SRType_LSL, 0);
5755      shift_t = SRType_LSL;
5756      shift_n = 0;
5757
5758      // if t == 15 || m == 15 then UNPREDICTABLE;
5759      if ((t == 15) || (m == 15))
5760        return false;
5761
5762      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5763      if (wback && ((n == 15) || (n == t)))
5764        return false;
5765
5766      break;
5767
5768    default:
5769      return false;
5770    }
5771
5772    uint32_t Rm = ReadCoreReg(m, &success);
5773    if (!success)
5774      return false;
5775
5776    uint32_t Rn = ReadCoreReg(n, &success);
5777    if (!success)
5778      return false;
5779
5780    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5781    uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5782    if (!success)
5783      return false;
5784
5785    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5786    addr_t offset_addr;
5787    if (add)
5788      offset_addr = Rn + offset;
5789    else
5790      offset_addr = Rn - offset;
5791
5792    // address = if index then offset_addr else R[n];
5793    addr_t address;
5794    if (index)
5795      address = offset_addr;
5796    else
5797      address = Rn;
5798
5799    EmulateInstruction::Context context;
5800    context.type = eContextRegisterStore;
5801    RegisterInfo base_reg;
5802    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5803    RegisterInfo offset_reg;
5804    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5805
5806    // if UnalignedSupport() || address<0> == '0' then
5807    if (UnalignedSupport() || BitIsClear(address, 0)) {
5808      // MemU[address,2] = R[t]<15:0>;
5809      uint32_t Rt = ReadCoreReg(t, &success);
5810      if (!success)
5811        return false;
5812
5813      EmulateInstruction::Context context;
5814      context.type = eContextRegisterStore;
5815      RegisterInfo base_reg;
5816      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5817      RegisterInfo offset_reg;
5818      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5819      RegisterInfo data_reg;
5820      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5821      context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5822                                                      data_reg);
5823
5824      if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5825        return false;
5826    } else // Can only occur before ARMv7
5827    {
5828      // MemU[address,2] = bits(16) UNKNOWN;
5829    }
5830
5831    // if wback then R[n] = offset_addr;
5832    if (wback) {
5833      context.type = eContextAdjustBaseRegister;
5834      context.SetAddress(offset_addr);
5835      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5836                                 offset_addr))
5837        return false;
5838    }
5839  }
5840
5841  return true;
5842}
5843
5844// Add with Carry (immediate) adds an immediate value and the carry flag value
5845// to a register value,
5846// and writes the result to the destination register.  It can optionally update
5847// the condition flags
5848// based on the result.
5849bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5850                                          const ARMEncoding encoding) {
5851#if 0
5852    // ARM pseudo code...
5853    if ConditionPassed() then
5854        EncodingSpecificOperations();
5855        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5856        if d == 15 then         // Can only occur for ARM encoding
5857            ALUWritePC(result); // setflags is always FALSE here
5858        else
5859            R[d] = result;
5860            if setflags then
5861                APSR.N = result<31>;
5862                APSR.Z = IsZeroBit(result);
5863                APSR.C = carry;
5864                APSR.V = overflow;
5865#endif
5866
5867  bool success = false;
5868
5869  if (ConditionPassed(opcode)) {
5870    uint32_t Rd, Rn;
5871    uint32_t
5872        imm32; // the immediate value to be added to the value obtained from Rn
5873    bool setflags;
5874    switch (encoding) {
5875    case eEncodingT1:
5876      Rd = Bits32(opcode, 11, 8);
5877      Rn = Bits32(opcode, 19, 16);
5878      setflags = BitIsSet(opcode, 20);
5879      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5880      if (BadReg(Rd) || BadReg(Rn))
5881        return false;
5882      break;
5883    case eEncodingA1:
5884      Rd = Bits32(opcode, 15, 12);
5885      Rn = Bits32(opcode, 19, 16);
5886      setflags = BitIsSet(opcode, 20);
5887      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5888
5889      if (Rd == 15 && setflags)
5890        return EmulateSUBSPcLrEtc(opcode, encoding);
5891      break;
5892    default:
5893      return false;
5894    }
5895
5896    // Read the first operand.
5897    int32_t val1 = ReadCoreReg(Rn, &success);
5898    if (!success)
5899      return false;
5900
5901    AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5902
5903    EmulateInstruction::Context context;
5904    context.type = EmulateInstruction::eContextImmediate;
5905    context.SetNoArgs();
5906
5907    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5908                                   res.carry_out, res.overflow))
5909      return false;
5910  }
5911  return true;
5912}
5913
5914// Add with Carry (register) adds a register value, the carry flag value, and an
5915// optionally-shifted
5916// register value, and writes the result to the destination register.  It can
5917// optionally update the
5918// condition flags based on the result.
5919bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5920                                          const ARMEncoding encoding) {
5921#if 0
5922    // ARM pseudo code...
5923    if ConditionPassed() then
5924        EncodingSpecificOperations();
5925        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5926        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5927        if d == 15 then         // Can only occur for ARM encoding
5928            ALUWritePC(result); // setflags is always FALSE here
5929        else
5930            R[d] = result;
5931            if setflags then
5932                APSR.N = result<31>;
5933                APSR.Z = IsZeroBit(result);
5934                APSR.C = carry;
5935                APSR.V = overflow;
5936#endif
5937
5938  bool success = false;
5939
5940  if (ConditionPassed(opcode)) {
5941    uint32_t Rd, Rn, Rm;
5942    ARM_ShifterType shift_t;
5943    uint32_t shift_n; // the shift applied to the value read from Rm
5944    bool setflags;
5945    switch (encoding) {
5946    case eEncodingT1:
5947      Rd = Rn = Bits32(opcode, 2, 0);
5948      Rm = Bits32(opcode, 5, 3);
5949      setflags = !InITBlock();
5950      shift_t = SRType_LSL;
5951      shift_n = 0;
5952      break;
5953    case eEncodingT2:
5954      Rd = Bits32(opcode, 11, 8);
5955      Rn = Bits32(opcode, 19, 16);
5956      Rm = Bits32(opcode, 3, 0);
5957      setflags = BitIsSet(opcode, 20);
5958      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5959      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5960        return false;
5961      break;
5962    case eEncodingA1:
5963      Rd = Bits32(opcode, 15, 12);
5964      Rn = Bits32(opcode, 19, 16);
5965      Rm = Bits32(opcode, 3, 0);
5966      setflags = BitIsSet(opcode, 20);
5967      shift_n = DecodeImmShiftARM(opcode, shift_t);
5968
5969      if (Rd == 15 && setflags)
5970        return EmulateSUBSPcLrEtc(opcode, encoding);
5971      break;
5972    default:
5973      return false;
5974    }
5975
5976    // Read the first operand.
5977    int32_t val1 = ReadCoreReg(Rn, &success);
5978    if (!success)
5979      return false;
5980
5981    // Read the second operand.
5982    int32_t val2 = ReadCoreReg(Rm, &success);
5983    if (!success)
5984      return false;
5985
5986    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5987    if (!success)
5988      return false;
5989    AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5990
5991    EmulateInstruction::Context context;
5992    context.type = EmulateInstruction::eContextImmediate;
5993    context.SetNoArgs();
5994
5995    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5996                                   res.carry_out, res.overflow))
5997      return false;
5998  }
5999  return true;
6000}
6001
6002// This instruction adds an immediate value to the PC value to form a
6003// PC-relative address,
6004// and writes the result to the destination register.
6005bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
6006                                       const ARMEncoding encoding) {
6007#if 0
6008    // ARM pseudo code...
6009    if ConditionPassed() then
6010        EncodingSpecificOperations();
6011        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
6012        if d == 15 then         // Can only occur for ARM encodings
6013            ALUWritePC(result);
6014        else
6015            R[d] = result;
6016#endif
6017
6018  bool success = false;
6019
6020  if (ConditionPassed(opcode)) {
6021    uint32_t Rd;
6022    uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
6023    bool add;
6024    switch (encoding) {
6025    case eEncodingT1:
6026      Rd = Bits32(opcode, 10, 8);
6027      imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
6028      add = true;
6029      break;
6030    case eEncodingT2:
6031    case eEncodingT3:
6032      Rd = Bits32(opcode, 11, 8);
6033      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
6034      add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
6035      if (BadReg(Rd))
6036        return false;
6037      break;
6038    case eEncodingA1:
6039    case eEncodingA2:
6040      Rd = Bits32(opcode, 15, 12);
6041      imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
6042      add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
6043      break;
6044    default:
6045      return false;
6046    }
6047
6048    // Read the PC value.
6049    uint32_t pc = ReadCoreReg(PC_REG, &success);
6050    if (!success)
6051      return false;
6052
6053    uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6054
6055    EmulateInstruction::Context context;
6056    context.type = EmulateInstruction::eContextImmediate;
6057    context.SetNoArgs();
6058
6059    if (!WriteCoreReg(context, result, Rd))
6060      return false;
6061  }
6062  return true;
6063}
6064
6065// This instruction performs a bitwise AND of a register value and an immediate
6066// value, and writes the result
6067// to the destination register.  It can optionally update the condition flags
6068// based on the result.
6069bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6070                                          const ARMEncoding encoding) {
6071#if 0
6072    // ARM pseudo code...
6073    if ConditionPassed() then
6074        EncodingSpecificOperations();
6075        result = R[n] AND imm32;
6076        if d == 15 then         // Can only occur for ARM encoding
6077            ALUWritePC(result); // setflags is always FALSE here
6078        else
6079            R[d] = result;
6080            if setflags then
6081                APSR.N = result<31>;
6082                APSR.Z = IsZeroBit(result);
6083                APSR.C = carry;
6084                // APSR.V unchanged
6085#endif
6086
6087  bool success = false;
6088
6089  if (ConditionPassed(opcode)) {
6090    uint32_t Rd, Rn;
6091    uint32_t
6092        imm32; // the immediate value to be ANDed to the value obtained from Rn
6093    bool setflags;
6094    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6095    switch (encoding) {
6096    case eEncodingT1:
6097      Rd = Bits32(opcode, 11, 8);
6098      Rn = Bits32(opcode, 19, 16);
6099      setflags = BitIsSet(opcode, 20);
6100      imm32 = ThumbExpandImm_C(
6101          opcode, APSR_C,
6102          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6103      // if Rd == '1111' && S == '1' then SEE TST (immediate);
6104      if (Rd == 15 && setflags)
6105        return EmulateTSTImm(opcode, eEncodingT1);
6106      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6107        return false;
6108      break;
6109    case eEncodingA1:
6110      Rd = Bits32(opcode, 15, 12);
6111      Rn = Bits32(opcode, 19, 16);
6112      setflags = BitIsSet(opcode, 20);
6113      imm32 =
6114          ARMExpandImm_C(opcode, APSR_C,
6115                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6116
6117      if (Rd == 15 && setflags)
6118        return EmulateSUBSPcLrEtc(opcode, encoding);
6119      break;
6120    default:
6121      return false;
6122    }
6123
6124    // Read the first operand.
6125    uint32_t val1 = ReadCoreReg(Rn, &success);
6126    if (!success)
6127      return false;
6128
6129    uint32_t result = val1 & imm32;
6130
6131    EmulateInstruction::Context context;
6132    context.type = EmulateInstruction::eContextImmediate;
6133    context.SetNoArgs();
6134
6135    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6136      return false;
6137  }
6138  return true;
6139}
6140
6141// This instruction performs a bitwise AND of a register value and an
6142// optionally-shifted register value,
6143// and writes the result to the destination register.  It can optionally update
6144// the condition flags
6145// based on the result.
6146bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6147                                          const ARMEncoding encoding) {
6148#if 0
6149    // ARM pseudo code...
6150    if ConditionPassed() then
6151        EncodingSpecificOperations();
6152        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6153        result = R[n] AND shifted;
6154        if d == 15 then         // Can only occur for ARM encoding
6155            ALUWritePC(result); // setflags is always FALSE here
6156        else
6157            R[d] = result;
6158            if setflags then
6159                APSR.N = result<31>;
6160                APSR.Z = IsZeroBit(result);
6161                APSR.C = carry;
6162                // APSR.V unchanged
6163#endif
6164
6165  bool success = false;
6166
6167  if (ConditionPassed(opcode)) {
6168    uint32_t Rd, Rn, Rm;
6169    ARM_ShifterType shift_t;
6170    uint32_t shift_n; // the shift applied to the value read from Rm
6171    bool setflags;
6172    uint32_t carry;
6173    switch (encoding) {
6174    case eEncodingT1:
6175      Rd = Rn = Bits32(opcode, 2, 0);
6176      Rm = Bits32(opcode, 5, 3);
6177      setflags = !InITBlock();
6178      shift_t = SRType_LSL;
6179      shift_n = 0;
6180      break;
6181    case eEncodingT2:
6182      Rd = Bits32(opcode, 11, 8);
6183      Rn = Bits32(opcode, 19, 16);
6184      Rm = Bits32(opcode, 3, 0);
6185      setflags = BitIsSet(opcode, 20);
6186      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6187      // if Rd == '1111' && S == '1' then SEE TST (register);
6188      if (Rd == 15 && setflags)
6189        return EmulateTSTReg(opcode, eEncodingT2);
6190      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6191        return false;
6192      break;
6193    case eEncodingA1:
6194      Rd = Bits32(opcode, 15, 12);
6195      Rn = Bits32(opcode, 19, 16);
6196      Rm = Bits32(opcode, 3, 0);
6197      setflags = BitIsSet(opcode, 20);
6198      shift_n = DecodeImmShiftARM(opcode, shift_t);
6199
6200      if (Rd == 15 && setflags)
6201        return EmulateSUBSPcLrEtc(opcode, encoding);
6202      break;
6203    default:
6204      return false;
6205    }
6206
6207    // Read the first operand.
6208    uint32_t val1 = ReadCoreReg(Rn, &success);
6209    if (!success)
6210      return false;
6211
6212    // Read the second operand.
6213    uint32_t val2 = ReadCoreReg(Rm, &success);
6214    if (!success)
6215      return false;
6216
6217    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6218    if (!success)
6219      return false;
6220    uint32_t result = val1 & shifted;
6221
6222    EmulateInstruction::Context context;
6223    context.type = EmulateInstruction::eContextImmediate;
6224    context.SetNoArgs();
6225
6226    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6227      return false;
6228  }
6229  return true;
6230}
6231
6232// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6233// the complement of an
6234// immediate value, and writes the result to the destination register.  It can
6235// optionally update the
6236// condition flags based on the result.
6237bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6238                                          const ARMEncoding encoding) {
6239#if 0
6240    // ARM pseudo code...
6241    if ConditionPassed() then
6242        EncodingSpecificOperations();
6243        result = R[n] AND NOT(imm32);
6244        if d == 15 then         // Can only occur for ARM encoding
6245            ALUWritePC(result); // setflags is always FALSE here
6246        else
6247            R[d] = result;
6248            if setflags then
6249                APSR.N = result<31>;
6250                APSR.Z = IsZeroBit(result);
6251                APSR.C = carry;
6252                // APSR.V unchanged
6253#endif
6254
6255  bool success = false;
6256
6257  if (ConditionPassed(opcode)) {
6258    uint32_t Rd, Rn;
6259    uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6260                    // the value obtained from Rn
6261    bool setflags;
6262    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6263    switch (encoding) {
6264    case eEncodingT1:
6265      Rd = Bits32(opcode, 11, 8);
6266      Rn = Bits32(opcode, 19, 16);
6267      setflags = BitIsSet(opcode, 20);
6268      imm32 = ThumbExpandImm_C(
6269          opcode, APSR_C,
6270          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6271      if (BadReg(Rd) || BadReg(Rn))
6272        return false;
6273      break;
6274    case eEncodingA1:
6275      Rd = Bits32(opcode, 15, 12);
6276      Rn = Bits32(opcode, 19, 16);
6277      setflags = BitIsSet(opcode, 20);
6278      imm32 =
6279          ARMExpandImm_C(opcode, APSR_C,
6280                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6281
6282      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6283      // instructions;
6284      if (Rd == 15 && setflags)
6285        return EmulateSUBSPcLrEtc(opcode, encoding);
6286      break;
6287    default:
6288      return false;
6289    }
6290
6291    // Read the first operand.
6292    uint32_t val1 = ReadCoreReg(Rn, &success);
6293    if (!success)
6294      return false;
6295
6296    uint32_t result = val1 & ~imm32;
6297
6298    EmulateInstruction::Context context;
6299    context.type = EmulateInstruction::eContextImmediate;
6300    context.SetNoArgs();
6301
6302    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6303      return false;
6304  }
6305  return true;
6306}
6307
6308// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6309// the complement of an
6310// optionally-shifted register value, and writes the result to the destination
6311// register.
6312// It can optionally update the condition flags based on the result.
6313bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6314                                          const ARMEncoding encoding) {
6315#if 0
6316    // ARM pseudo code...
6317    if ConditionPassed() then
6318        EncodingSpecificOperations();
6319        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6320        result = R[n] AND NOT(shifted);
6321        if d == 15 then         // Can only occur for ARM encoding
6322            ALUWritePC(result); // setflags is always FALSE here
6323        else
6324            R[d] = result;
6325            if setflags then
6326                APSR.N = result<31>;
6327                APSR.Z = IsZeroBit(result);
6328                APSR.C = carry;
6329                // APSR.V unchanged
6330#endif
6331
6332  bool success = false;
6333
6334  if (ConditionPassed(opcode)) {
6335    uint32_t Rd, Rn, Rm;
6336    ARM_ShifterType shift_t;
6337    uint32_t shift_n; // the shift applied to the value read from Rm
6338    bool setflags;
6339    uint32_t carry;
6340    switch (encoding) {
6341    case eEncodingT1:
6342      Rd = Rn = Bits32(opcode, 2, 0);
6343      Rm = Bits32(opcode, 5, 3);
6344      setflags = !InITBlock();
6345      shift_t = SRType_LSL;
6346      shift_n = 0;
6347      break;
6348    case eEncodingT2:
6349      Rd = Bits32(opcode, 11, 8);
6350      Rn = Bits32(opcode, 19, 16);
6351      Rm = Bits32(opcode, 3, 0);
6352      setflags = BitIsSet(opcode, 20);
6353      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6354      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6355        return false;
6356      break;
6357    case eEncodingA1:
6358      Rd = Bits32(opcode, 15, 12);
6359      Rn = Bits32(opcode, 19, 16);
6360      Rm = Bits32(opcode, 3, 0);
6361      setflags = BitIsSet(opcode, 20);
6362      shift_n = DecodeImmShiftARM(opcode, shift_t);
6363
6364      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6365      // instructions;
6366      if (Rd == 15 && setflags)
6367        return EmulateSUBSPcLrEtc(opcode, encoding);
6368      break;
6369    default:
6370      return false;
6371    }
6372
6373    // Read the first operand.
6374    uint32_t val1 = ReadCoreReg(Rn, &success);
6375    if (!success)
6376      return false;
6377
6378    // Read the second operand.
6379    uint32_t val2 = ReadCoreReg(Rm, &success);
6380    if (!success)
6381      return false;
6382
6383    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6384    if (!success)
6385      return false;
6386    uint32_t result = val1 & ~shifted;
6387
6388    EmulateInstruction::Context context;
6389    context.type = EmulateInstruction::eContextImmediate;
6390    context.SetNoArgs();
6391
6392    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6393      return false;
6394  }
6395  return true;
6396}
6397
6398// LDR (immediate, ARM) calculates an address from a base register value and an
6399// immediate offset, loads a word
6400// from memory, and writes it to a register.  It can use offset, post-indexed,
6401// or pre-indexed addressing.
6402bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6403                                                   const ARMEncoding encoding) {
6404#if 0
6405    if ConditionPassed() then
6406        EncodingSpecificOperations();
6407        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6408        address = if index then offset_addr else R[n];
6409        data = MemU[address,4];
6410        if wback then R[n] = offset_addr;
6411        if t == 15 then
6412            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6413        elsif UnalignedSupport() || address<1:0> = '00' then
6414            R[t] = data;
6415        else // Can only apply before ARMv7
6416            R[t] = ROR(data, 8*UInt(address<1:0>));
6417#endif
6418
6419  bool success = false;
6420
6421  if (ConditionPassed(opcode)) {
6422    const uint32_t addr_byte_size = GetAddressByteSize();
6423
6424    uint32_t t;
6425    uint32_t n;
6426    uint32_t imm32;
6427    bool index;
6428    bool add;
6429    bool wback;
6430
6431    switch (encoding) {
6432    case eEncodingA1:
6433      // if Rn == '1111' then SEE LDR (literal);
6434      // if P == '0' && W == '1' then SEE LDRT;
6435      // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6436      // '000000000100' then SEE POP;
6437      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6438      t = Bits32(opcode, 15, 12);
6439      n = Bits32(opcode, 19, 16);
6440      imm32 = Bits32(opcode, 11, 0);
6441
6442      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
6443      // (W == '1');
6444      index = BitIsSet(opcode, 24);
6445      add = BitIsSet(opcode, 23);
6446      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6447
6448      // if wback && n == t then UNPREDICTABLE;
6449      if (wback && (n == t))
6450        return false;
6451
6452      break;
6453
6454    default:
6455      return false;
6456    }
6457
6458    addr_t address;
6459    addr_t offset_addr;
6460    addr_t base_address = ReadCoreReg(n, &success);
6461    if (!success)
6462      return false;
6463
6464    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6465    if (add)
6466      offset_addr = base_address + imm32;
6467    else
6468      offset_addr = base_address - imm32;
6469
6470    // address = if index then offset_addr else R[n];
6471    if (index)
6472      address = offset_addr;
6473    else
6474      address = base_address;
6475
6476    // data = MemU[address,4];
6477
6478    RegisterInfo base_reg;
6479    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6480
6481    EmulateInstruction::Context context;
6482    context.type = eContextRegisterLoad;
6483    context.SetRegisterPlusOffset(base_reg, address - base_address);
6484
6485    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6486    if (!success)
6487      return false;
6488
6489    // if wback then R[n] = offset_addr;
6490    if (wback) {
6491      context.type = eContextAdjustBaseRegister;
6492      context.SetAddress(offset_addr);
6493      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6494                                 offset_addr))
6495        return false;
6496    }
6497
6498    // if t == 15 then
6499    if (t == 15) {
6500      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6501      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6502        // LoadWritePC (data);
6503        context.type = eContextRegisterLoad;
6504        context.SetRegisterPlusOffset(base_reg, address - base_address);
6505        LoadWritePC(context, data);
6506      } else
6507        return false;
6508    }
6509    // elsif UnalignedSupport() || address<1:0> = '00' then
6510    else if (UnalignedSupport() ||
6511             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6512      // R[t] = data;
6513      context.type = eContextRegisterLoad;
6514      context.SetRegisterPlusOffset(base_reg, address - base_address);
6515      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6516                                 data))
6517        return false;
6518    }
6519    // else // Can only apply before ARMv7
6520    else {
6521      // R[t] = ROR(data, 8*UInt(address<1:0>));
6522      data = ROR(data, Bits32(address, 1, 0), &success);
6523      if (!success)
6524        return false;
6525      context.type = eContextRegisterLoad;
6526      context.SetImmediate(data);
6527      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6528                                 data))
6529        return false;
6530    }
6531  }
6532  return true;
6533}
6534
6535// LDR (register) calculates an address from a base register value and an offset
6536// register value, loads a word
6537// from memory, and writes it to a register.  The offset register value can
6538// optionally be shifted.
6539bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6540                                               const ARMEncoding encoding) {
6541#if 0
6542    if ConditionPassed() then
6543        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6544        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6545        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6546        address = if index then offset_addr else R[n];
6547        data = MemU[address,4];
6548        if wback then R[n] = offset_addr;
6549        if t == 15 then
6550            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6551        elsif UnalignedSupport() || address<1:0> = '00' then
6552            R[t] = data;
6553        else // Can only apply before ARMv7
6554            if CurrentInstrSet() == InstrSet_ARM then
6555                R[t] = ROR(data, 8*UInt(address<1:0>));
6556            else
6557                R[t] = bits(32) UNKNOWN;
6558#endif
6559
6560  bool success = false;
6561
6562  if (ConditionPassed(opcode)) {
6563    const uint32_t addr_byte_size = GetAddressByteSize();
6564
6565    uint32_t t;
6566    uint32_t n;
6567    uint32_t m;
6568    bool index;
6569    bool add;
6570    bool wback;
6571    ARM_ShifterType shift_t;
6572    uint32_t shift_n;
6573
6574    switch (encoding) {
6575    case eEncodingT1:
6576      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6577      // in ThumbEE";
6578      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6579      t = Bits32(opcode, 2, 0);
6580      n = Bits32(opcode, 5, 3);
6581      m = Bits32(opcode, 8, 6);
6582
6583      // index = TRUE; add = TRUE; wback = FALSE;
6584      index = true;
6585      add = true;
6586      wback = false;
6587
6588      // (shift_t, shift_n) = (SRType_LSL, 0);
6589      shift_t = SRType_LSL;
6590      shift_n = 0;
6591
6592      break;
6593
6594    case eEncodingT2:
6595      // if Rn == '1111' then SEE LDR (literal);
6596      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6597      t = Bits32(opcode, 15, 12);
6598      n = Bits32(opcode, 19, 16);
6599      m = Bits32(opcode, 3, 0);
6600
6601      // index = TRUE; add = TRUE; wback = FALSE;
6602      index = true;
6603      add = true;
6604      wback = false;
6605
6606      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6607      shift_t = SRType_LSL;
6608      shift_n = Bits32(opcode, 5, 4);
6609
6610      // if BadReg(m) then UNPREDICTABLE;
6611      if (BadReg(m))
6612        return false;
6613
6614      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6615      if ((t == 15) && InITBlock() && !LastInITBlock())
6616        return false;
6617
6618      break;
6619
6620    case eEncodingA1: {
6621      // if P == '0' && W == '1' then SEE LDRT;
6622      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6623      t = Bits32(opcode, 15, 12);
6624      n = Bits32(opcode, 19, 16);
6625      m = Bits32(opcode, 3, 0);
6626
6627      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
6628      // (W == '1');
6629      index = BitIsSet(opcode, 24);
6630      add = BitIsSet(opcode, 23);
6631      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6632
6633      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6634      uint32_t type = Bits32(opcode, 6, 5);
6635      uint32_t imm5 = Bits32(opcode, 11, 7);
6636      shift_n = DecodeImmShift(type, imm5, shift_t);
6637
6638      // if m == 15 then UNPREDICTABLE;
6639      if (m == 15)
6640        return false;
6641
6642      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6643      if (wback && ((n == 15) || (n == t)))
6644        return false;
6645    } break;
6646
6647    default:
6648      return false;
6649    }
6650
6651    uint32_t Rm =
6652        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6653    if (!success)
6654      return false;
6655
6656    uint32_t Rn =
6657        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6658    if (!success)
6659      return false;
6660
6661    addr_t offset_addr;
6662    addr_t address;
6663
6664    // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an
6665    // application level alias for the CPSR".
6666    addr_t offset =
6667        Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6668    if (!success)
6669      return false;
6670
6671    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6672    if (add)
6673      offset_addr = Rn + offset;
6674    else
6675      offset_addr = Rn - offset;
6676
6677    // address = if index then offset_addr else R[n];
6678    if (index)
6679      address = offset_addr;
6680    else
6681      address = Rn;
6682
6683    // data = MemU[address,4];
6684    RegisterInfo base_reg;
6685    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6686
6687    EmulateInstruction::Context context;
6688    context.type = eContextRegisterLoad;
6689    context.SetRegisterPlusOffset(base_reg, address - Rn);
6690
6691    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6692    if (!success)
6693      return false;
6694
6695    // if wback then R[n] = offset_addr;
6696    if (wback) {
6697      context.type = eContextAdjustBaseRegister;
6698      context.SetAddress(offset_addr);
6699      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6700                                 offset_addr))
6701        return false;
6702    }
6703
6704    // if t == 15 then
6705    if (t == 15) {
6706      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6707      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6708        context.type = eContextRegisterLoad;
6709        context.SetRegisterPlusOffset(base_reg, address - Rn);
6710        LoadWritePC(context, data);
6711      } else
6712        return false;
6713    }
6714    // elsif UnalignedSupport() || address<1:0> = '00' then
6715    else if (UnalignedSupport() ||
6716             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6717      // R[t] = data;
6718      context.type = eContextRegisterLoad;
6719      context.SetRegisterPlusOffset(base_reg, address - Rn);
6720      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6721                                 data))
6722        return false;
6723    } else // Can only apply before ARMv7
6724    {
6725      // if CurrentInstrSet() == InstrSet_ARM then
6726      if (CurrentInstrSet() == eModeARM) {
6727        // R[t] = ROR(data, 8*UInt(address<1:0>));
6728        data = ROR(data, Bits32(address, 1, 0), &success);
6729        if (!success)
6730          return false;
6731        context.type = eContextRegisterLoad;
6732        context.SetImmediate(data);
6733        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6734                                   data))
6735          return false;
6736      } else {
6737        // R[t] = bits(32) UNKNOWN;
6738        WriteBits32Unknown(t);
6739      }
6740    }
6741  }
6742  return true;
6743}
6744
6745// LDRB (immediate, Thumb)
6746bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6747                                                 const ARMEncoding encoding) {
6748#if 0
6749    if ConditionPassed() then
6750        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6751        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6752        address = if index then offset_addr else R[n];
6753        R[t] = ZeroExtend(MemU[address,1], 32);
6754        if wback then R[n] = offset_addr;
6755#endif
6756
6757  bool success = false;
6758
6759  if (ConditionPassed(opcode)) {
6760    uint32_t t;
6761    uint32_t n;
6762    uint32_t imm32;
6763    bool index;
6764    bool add;
6765    bool wback;
6766
6767    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6768    switch (encoding) {
6769    case eEncodingT1:
6770      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6771      t = Bits32(opcode, 2, 0);
6772      n = Bits32(opcode, 5, 3);
6773      imm32 = Bits32(opcode, 10, 6);
6774
6775      // index = TRUE; add = TRUE; wback = FALSE;
6776      index = true;
6777      add = true;
6778      wback = false;
6779
6780      break;
6781
6782    case eEncodingT2:
6783      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6784      t = Bits32(opcode, 15, 12);
6785      n = Bits32(opcode, 19, 16);
6786      imm32 = Bits32(opcode, 11, 0);
6787
6788      // index = TRUE; add = TRUE; wback = FALSE;
6789      index = true;
6790      add = true;
6791      wback = false;
6792
6793      // if Rt == '1111' then SEE PLD;
6794      if (t == 15)
6795        return false; // PLD is not implemented yet
6796
6797      // if Rn == '1111' then SEE LDRB (literal);
6798      if (n == 15)
6799        return EmulateLDRBLiteral(opcode, eEncodingT1);
6800
6801      // if t == 13 then UNPREDICTABLE;
6802      if (t == 13)
6803        return false;
6804
6805      break;
6806
6807    case eEncodingT3:
6808      // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6809      // if P == '0' && W == '0' then UNDEFINED;
6810      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6811        return false;
6812
6813      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6814      t = Bits32(opcode, 15, 12);
6815      n = Bits32(opcode, 19, 16);
6816      imm32 = Bits32(opcode, 7, 0);
6817
6818      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6819      index = BitIsSet(opcode, 10);
6820      add = BitIsSet(opcode, 9);
6821      wback = BitIsSet(opcode, 8);
6822
6823      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6824      if (t == 15)
6825        return false; // PLD is not implemented yet
6826
6827      // if Rn == '1111' then SEE LDRB (literal);
6828      if (n == 15)
6829        return EmulateLDRBLiteral(opcode, eEncodingT1);
6830
6831      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6832      if (BadReg(t) || (wback && (n == t)))
6833        return false;
6834
6835      break;
6836
6837    default:
6838      return false;
6839    }
6840
6841    uint32_t Rn =
6842        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6843    if (!success)
6844      return false;
6845
6846    addr_t address;
6847    addr_t offset_addr;
6848
6849    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6850    if (add)
6851      offset_addr = Rn + imm32;
6852    else
6853      offset_addr = Rn - imm32;
6854
6855    // address = if index then offset_addr else R[n];
6856    if (index)
6857      address = offset_addr;
6858    else
6859      address = Rn;
6860
6861    // R[t] = ZeroExtend(MemU[address,1], 32);
6862    RegisterInfo base_reg;
6863    RegisterInfo data_reg;
6864    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6865    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6866
6867    EmulateInstruction::Context context;
6868    context.type = eContextRegisterLoad;
6869    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6870
6871    uint64_t data = MemURead(context, address, 1, 0, &success);
6872    if (!success)
6873      return false;
6874
6875    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6876      return false;
6877
6878    // if wback then R[n] = offset_addr;
6879    if (wback) {
6880      context.type = eContextAdjustBaseRegister;
6881      context.SetAddress(offset_addr);
6882      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6883                                 offset_addr))
6884        return false;
6885    }
6886  }
6887  return true;
6888}
6889
6890// LDRB (literal) calculates an address from the PC value and an immediate
6891// offset, loads a byte from memory,
6892// zero-extends it to form a 32-bit word and writes it to a register.
6893bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6894                                               const ARMEncoding encoding) {
6895#if 0
6896    if ConditionPassed() then
6897        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6898        base = Align(PC,4);
6899        address = if add then (base + imm32) else (base - imm32);
6900        R[t] = ZeroExtend(MemU[address,1], 32);
6901#endif
6902
6903  bool success = false;
6904
6905  if (ConditionPassed(opcode)) {
6906    uint32_t t;
6907    uint32_t imm32;
6908    bool add;
6909    switch (encoding) {
6910    case eEncodingT1:
6911      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6912      t = Bits32(opcode, 15, 12);
6913      imm32 = Bits32(opcode, 11, 0);
6914      add = BitIsSet(opcode, 23);
6915
6916      // if Rt == '1111' then SEE PLD;
6917      if (t == 15)
6918        return false; // PLD is not implemented yet
6919
6920      // if t == 13 then UNPREDICTABLE;
6921      if (t == 13)
6922        return false;
6923
6924      break;
6925
6926    case eEncodingA1:
6927      // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6928      t = Bits32(opcode, 15, 12);
6929      imm32 = Bits32(opcode, 11, 0);
6930      add = BitIsSet(opcode, 23);
6931
6932      // if t == 15 then UNPREDICTABLE;
6933      if (t == 15)
6934        return false;
6935      break;
6936
6937    default:
6938      return false;
6939    }
6940
6941    // base = Align(PC,4);
6942    uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6943    if (!success)
6944      return false;
6945
6946    uint32_t base = AlignPC(pc_val);
6947
6948    addr_t address;
6949    // address = if add then (base + imm32) else (base - imm32);
6950    if (add)
6951      address = base + imm32;
6952    else
6953      address = base - imm32;
6954
6955    // R[t] = ZeroExtend(MemU[address,1], 32);
6956    EmulateInstruction::Context context;
6957    context.type = eContextRelativeBranchImmediate;
6958    context.SetImmediate(address - base);
6959
6960    uint64_t data = MemURead(context, address, 1, 0, &success);
6961    if (!success)
6962      return false;
6963
6964    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6965      return false;
6966  }
6967  return true;
6968}
6969
6970// LDRB (register) calculates an address from a base register value and an
6971// offset rigister value, loads a byte from
6972// memory, zero-extends it to form a 32-bit word, and writes it to a register.
6973// The offset register value can
6974// optionally be shifted.
6975bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6976                                                const ARMEncoding encoding) {
6977#if 0
6978    if ConditionPassed() then
6979        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6980        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6981        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6982        address = if index then offset_addr else R[n];
6983        R[t] = ZeroExtend(MemU[address,1],32);
6984        if wback then R[n] = offset_addr;
6985#endif
6986
6987  bool success = false;
6988
6989  if (ConditionPassed(opcode)) {
6990    uint32_t t;
6991    uint32_t n;
6992    uint32_t m;
6993    bool index;
6994    bool add;
6995    bool wback;
6996    ARM_ShifterType shift_t;
6997    uint32_t shift_n;
6998
6999    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7000    switch (encoding) {
7001    case eEncodingT1:
7002      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7003      t = Bits32(opcode, 2, 0);
7004      n = Bits32(opcode, 5, 3);
7005      m = Bits32(opcode, 8, 6);
7006
7007      // index = TRUE; add = TRUE; wback = FALSE;
7008      index = true;
7009      add = true;
7010      wback = false;
7011
7012      // (shift_t, shift_n) = (SRType_LSL, 0);
7013      shift_t = SRType_LSL;
7014      shift_n = 0;
7015      break;
7016
7017    case eEncodingT2:
7018      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7019      t = Bits32(opcode, 15, 12);
7020      n = Bits32(opcode, 19, 16);
7021      m = Bits32(opcode, 3, 0);
7022
7023      // index = TRUE; add = TRUE; wback = FALSE;
7024      index = true;
7025      add = true;
7026      wback = false;
7027
7028      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7029      shift_t = SRType_LSL;
7030      shift_n = Bits32(opcode, 5, 4);
7031
7032      // if Rt == '1111' then SEE PLD;
7033      if (t == 15)
7034        return false; // PLD is not implemented yet
7035
7036      // if Rn == '1111' then SEE LDRB (literal);
7037      if (n == 15)
7038        return EmulateLDRBLiteral(opcode, eEncodingT1);
7039
7040      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7041      if ((t == 13) || BadReg(m))
7042        return false;
7043      break;
7044
7045    case eEncodingA1: {
7046      // if P == '0' && W == '1' then SEE LDRBT;
7047      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7048      t = Bits32(opcode, 15, 12);
7049      n = Bits32(opcode, 19, 16);
7050      m = Bits32(opcode, 3, 0);
7051
7052      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7053      // (W == '1');
7054      index = BitIsSet(opcode, 24);
7055      add = BitIsSet(opcode, 23);
7056      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7057
7058      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7059      uint32_t type = Bits32(opcode, 6, 5);
7060      uint32_t imm5 = Bits32(opcode, 11, 7);
7061      shift_n = DecodeImmShift(type, imm5, shift_t);
7062
7063      // if t == 15 || m == 15 then UNPREDICTABLE;
7064      if ((t == 15) || (m == 15))
7065        return false;
7066
7067      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7068      if (wback && ((n == 15) || (n == t)))
7069        return false;
7070    } break;
7071
7072    default:
7073      return false;
7074    }
7075
7076    addr_t offset_addr;
7077    addr_t address;
7078
7079    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7080    uint32_t Rm =
7081        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7082    if (!success)
7083      return false;
7084
7085    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7086    if (!success)
7087      return false;
7088
7089    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7090    uint32_t Rn =
7091        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7092    if (!success)
7093      return false;
7094
7095    if (add)
7096      offset_addr = Rn + offset;
7097    else
7098      offset_addr = Rn - offset;
7099
7100    // address = if index then offset_addr else R[n];
7101    if (index)
7102      address = offset_addr;
7103    else
7104      address = Rn;
7105
7106    // R[t] = ZeroExtend(MemU[address,1],32);
7107    RegisterInfo base_reg;
7108    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7109
7110    EmulateInstruction::Context context;
7111    context.type = eContextRegisterLoad;
7112    context.SetRegisterPlusOffset(base_reg, address - Rn);
7113
7114    uint64_t data = MemURead(context, address, 1, 0, &success);
7115    if (!success)
7116      return false;
7117
7118    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7119      return false;
7120
7121    // if wback then R[n] = offset_addr;
7122    if (wback) {
7123      context.type = eContextAdjustBaseRegister;
7124      context.SetAddress(offset_addr);
7125      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7126                                 offset_addr))
7127        return false;
7128    }
7129  }
7130  return true;
7131}
7132
7133// LDRH (immediate, Thumb) calculates an address from a base register value and
7134// an immediate offset, loads a
7135// halfword from memory, zero-extends it to form a 32-bit word, and writes it to
7136// a register.  It can use offset,
7137// post-indexed, or pre-indexed addressing.
7138bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7139                                                 const ARMEncoding encoding) {
7140#if 0
7141    if ConditionPassed() then
7142        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7143        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7144        address = if index then offset_addr else R[n];
7145        data = MemU[address,2];
7146        if wback then R[n] = offset_addr;
7147        if UnalignedSupport() || address<0> = '0' then
7148            R[t] = ZeroExtend(data, 32);
7149        else // Can only apply before ARMv7
7150            R[t] = bits(32) UNKNOWN;
7151#endif
7152
7153  bool success = false;
7154
7155  if (ConditionPassed(opcode)) {
7156    uint32_t t;
7157    uint32_t n;
7158    uint32_t imm32;
7159    bool index;
7160    bool add;
7161    bool wback;
7162
7163    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7164    switch (encoding) {
7165    case eEncodingT1:
7166      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7167      t = Bits32(opcode, 2, 0);
7168      n = Bits32(opcode, 5, 3);
7169      imm32 = Bits32(opcode, 10, 6) << 1;
7170
7171      // index = TRUE; add = TRUE; wback = FALSE;
7172      index = true;
7173      add = true;
7174      wback = false;
7175
7176      break;
7177
7178    case eEncodingT2:
7179      // if Rt == '1111' then SEE "Unallocated memory hints";
7180      // if Rn == '1111' then SEE LDRH (literal);
7181      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7182      t = Bits32(opcode, 15, 12);
7183      n = Bits32(opcode, 19, 16);
7184      imm32 = Bits32(opcode, 11, 0);
7185
7186      // index = TRUE; add = TRUE; wback = FALSE;
7187      index = true;
7188      add = true;
7189      wback = false;
7190
7191      // if t == 13 then UNPREDICTABLE;
7192      if (t == 13)
7193        return false;
7194      break;
7195
7196    case eEncodingT3:
7197      // if Rn == '1111' then SEE LDRH (literal);
7198      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7199      // "Unallocated memory hints";
7200      // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7201      // if P == '0' && W == '0' then UNDEFINED;
7202      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7203        return false;
7204
7205      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7206      t = Bits32(opcode, 15, 12);
7207      n = Bits32(opcode, 19, 16);
7208      imm32 = Bits32(opcode, 7, 0);
7209
7210      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7211      index = BitIsSet(opcode, 10);
7212      add = BitIsSet(opcode, 9);
7213      wback = BitIsSet(opcode, 8);
7214
7215      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7216      if (BadReg(t) || (wback && (n == t)))
7217        return false;
7218      break;
7219
7220    default:
7221      return false;
7222    }
7223
7224    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7225    uint32_t Rn =
7226        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7227    if (!success)
7228      return false;
7229
7230    addr_t offset_addr;
7231    addr_t address;
7232
7233    if (add)
7234      offset_addr = Rn + imm32;
7235    else
7236      offset_addr = Rn - imm32;
7237
7238    // address = if index then offset_addr else R[n];
7239    if (index)
7240      address = offset_addr;
7241    else
7242      address = Rn;
7243
7244    // data = MemU[address,2];
7245    RegisterInfo base_reg;
7246    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7247
7248    EmulateInstruction::Context context;
7249    context.type = eContextRegisterLoad;
7250    context.SetRegisterPlusOffset(base_reg, address - Rn);
7251
7252    uint64_t data = MemURead(context, address, 2, 0, &success);
7253    if (!success)
7254      return false;
7255
7256    // if wback then R[n] = offset_addr;
7257    if (wback) {
7258      context.type = eContextAdjustBaseRegister;
7259      context.SetAddress(offset_addr);
7260      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7261                                 offset_addr))
7262        return false;
7263    }
7264
7265    // if UnalignedSupport() || address<0> = '0' then
7266    if (UnalignedSupport() || BitIsClear(address, 0)) {
7267      // R[t] = ZeroExtend(data, 32);
7268      context.type = eContextRegisterLoad;
7269      context.SetRegisterPlusOffset(base_reg, address - Rn);
7270      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7271                                 data))
7272        return false;
7273    } else // Can only apply before ARMv7
7274    {
7275      // R[t] = bits(32) UNKNOWN;
7276      WriteBits32Unknown(t);
7277    }
7278  }
7279  return true;
7280}
7281
7282// LDRH (literal) caculates an address from the PC value and an immediate
7283// offset, loads a halfword from memory,
7284// zero-extends it to form a 32-bit word, and writes it to a register.
7285bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7286                                               const ARMEncoding encoding) {
7287#if 0
7288    if ConditionPassed() then
7289        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7290        base = Align(PC,4);
7291        address = if add then (base + imm32) else (base - imm32);
7292        data = MemU[address,2];
7293        if UnalignedSupport() || address<0> = '0' then
7294            R[t] = ZeroExtend(data, 32);
7295        else // Can only apply before ARMv7
7296            R[t] = bits(32) UNKNOWN;
7297#endif
7298
7299  bool success = false;
7300
7301  if (ConditionPassed(opcode)) {
7302    uint32_t t;
7303    uint32_t imm32;
7304    bool add;
7305
7306    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7307    switch (encoding) {
7308    case eEncodingT1:
7309      // if Rt == '1111' then SEE "Unallocated memory hints";
7310      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7311      t = Bits32(opcode, 15, 12);
7312      imm32 = Bits32(opcode, 11, 0);
7313      add = BitIsSet(opcode, 23);
7314
7315      // if t == 13 then UNPREDICTABLE;
7316      if (t == 13)
7317        return false;
7318
7319      break;
7320
7321    case eEncodingA1: {
7322      uint32_t imm4H = Bits32(opcode, 11, 8);
7323      uint32_t imm4L = Bits32(opcode, 3, 0);
7324
7325      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7326      t = Bits32(opcode, 15, 12);
7327      imm32 = (imm4H << 4) | imm4L;
7328      add = BitIsSet(opcode, 23);
7329
7330      // if t == 15 then UNPREDICTABLE;
7331      if (t == 15)
7332        return false;
7333      break;
7334    }
7335
7336    default:
7337      return false;
7338    }
7339
7340    // base = Align(PC,4);
7341    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7342    if (!success)
7343      return false;
7344
7345    addr_t base = AlignPC(pc_value);
7346    addr_t address;
7347
7348    // address = if add then (base + imm32) else (base - imm32);
7349    if (add)
7350      address = base + imm32;
7351    else
7352      address = base - imm32;
7353
7354    // data = MemU[address,2];
7355    RegisterInfo base_reg;
7356    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7357
7358    EmulateInstruction::Context context;
7359    context.type = eContextRegisterLoad;
7360    context.SetRegisterPlusOffset(base_reg, address - base);
7361
7362    uint64_t data = MemURead(context, address, 2, 0, &success);
7363    if (!success)
7364      return false;
7365
7366    // if UnalignedSupport() || address<0> = '0' then
7367    if (UnalignedSupport() || BitIsClear(address, 0)) {
7368      // R[t] = ZeroExtend(data, 32);
7369      context.type = eContextRegisterLoad;
7370      context.SetRegisterPlusOffset(base_reg, address - base);
7371      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7372                                 data))
7373        return false;
7374
7375    } else // Can only apply before ARMv7
7376    {
7377      // R[t] = bits(32) UNKNOWN;
7378      WriteBits32Unknown(t);
7379    }
7380  }
7381  return true;
7382}
7383
7384// LDRH (literal) calculates an address from a base register value and an offset
7385// register value, loads a halfword
7386// from memory, zero-extends it to form a 32-bit word, and writes it to a
7387// register.  The offset register value can
7388// be shifted left by 0, 1, 2, or 3 bits.
7389bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7390                                                const ARMEncoding encoding) {
7391#if 0
7392    if ConditionPassed() then
7393        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7394        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7395        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7396        address = if index then offset_addr else R[n];
7397        data = MemU[address,2];
7398        if wback then R[n] = offset_addr;
7399        if UnalignedSupport() || address<0> = '0' then
7400            R[t] = ZeroExtend(data, 32);
7401        else // Can only apply before ARMv7
7402            R[t] = bits(32) UNKNOWN;
7403#endif
7404
7405  bool success = false;
7406
7407  if (ConditionPassed(opcode)) {
7408    uint32_t t;
7409    uint32_t n;
7410    uint32_t m;
7411    bool index;
7412    bool add;
7413    bool wback;
7414    ARM_ShifterType shift_t;
7415    uint32_t shift_n;
7416
7417    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7418    switch (encoding) {
7419    case eEncodingT1:
7420      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7421      // in ThumbEE";
7422      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7423      t = Bits32(opcode, 2, 0);
7424      n = Bits32(opcode, 5, 3);
7425      m = Bits32(opcode, 8, 6);
7426
7427      // index = TRUE; add = TRUE; wback = FALSE;
7428      index = true;
7429      add = true;
7430      wback = false;
7431
7432      // (shift_t, shift_n) = (SRType_LSL, 0);
7433      shift_t = SRType_LSL;
7434      shift_n = 0;
7435
7436      break;
7437
7438    case eEncodingT2:
7439      // if Rn == '1111' then SEE LDRH (literal);
7440      // if Rt == '1111' then SEE "Unallocated memory hints";
7441      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7442      t = Bits32(opcode, 15, 12);
7443      n = Bits32(opcode, 19, 16);
7444      m = Bits32(opcode, 3, 0);
7445
7446      // index = TRUE; add = TRUE; wback = FALSE;
7447      index = true;
7448      add = true;
7449      wback = false;
7450
7451      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7452      shift_t = SRType_LSL;
7453      shift_n = Bits32(opcode, 5, 4);
7454
7455      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7456      if ((t == 13) || BadReg(m))
7457        return false;
7458      break;
7459
7460    case eEncodingA1:
7461      // if P == '0' && W == '1' then SEE LDRHT;
7462      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7463      t = Bits32(opcode, 15, 12);
7464      n = Bits32(opcode, 19, 16);
7465      m = Bits32(opcode, 3, 0);
7466
7467      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7468      // (W == '1');
7469      index = BitIsSet(opcode, 24);
7470      add = BitIsSet(opcode, 23);
7471      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7472
7473      // (shift_t, shift_n) = (SRType_LSL, 0);
7474      shift_t = SRType_LSL;
7475      shift_n = 0;
7476
7477      // if t == 15 || m == 15 then UNPREDICTABLE;
7478      if ((t == 15) || (m == 15))
7479        return false;
7480
7481      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7482      if (wback && ((n == 15) || (n == t)))
7483        return false;
7484
7485      break;
7486
7487    default:
7488      return false;
7489    }
7490
7491    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7492
7493    uint64_t Rm =
7494        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7495    if (!success)
7496      return false;
7497
7498    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7499    if (!success)
7500      return false;
7501
7502    addr_t offset_addr;
7503    addr_t address;
7504
7505    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7506    uint64_t Rn =
7507        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7508    if (!success)
7509      return false;
7510
7511    if (add)
7512      offset_addr = Rn + offset;
7513    else
7514      offset_addr = Rn - offset;
7515
7516    // address = if index then offset_addr else R[n];
7517    if (index)
7518      address = offset_addr;
7519    else
7520      address = Rn;
7521
7522    // data = MemU[address,2];
7523    RegisterInfo base_reg;
7524    RegisterInfo offset_reg;
7525    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7526    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7527
7528    EmulateInstruction::Context context;
7529    context.type = eContextRegisterLoad;
7530    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7531    uint64_t data = MemURead(context, address, 2, 0, &success);
7532    if (!success)
7533      return false;
7534
7535    // if wback then R[n] = offset_addr;
7536    if (wback) {
7537      context.type = eContextAdjustBaseRegister;
7538      context.SetAddress(offset_addr);
7539      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7540                                 offset_addr))
7541        return false;
7542    }
7543
7544    // if UnalignedSupport() || address<0> = '0' then
7545    if (UnalignedSupport() || BitIsClear(address, 0)) {
7546      // R[t] = ZeroExtend(data, 32);
7547      context.type = eContextRegisterLoad;
7548      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7549      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7550                                 data))
7551        return false;
7552    } else // Can only apply before ARMv7
7553    {
7554      // R[t] = bits(32) UNKNOWN;
7555      WriteBits32Unknown(t);
7556    }
7557  }
7558  return true;
7559}
7560
7561// LDRSB (immediate) calculates an address from a base register value and an
7562// immediate offset, loads a byte from
7563// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7564// It can use offset, post-indexed,
7565// or pre-indexed addressing.
7566bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7567                                                  const ARMEncoding encoding) {
7568#if 0
7569    if ConditionPassed() then
7570        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7571        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7572        address = if index then offset_addr else R[n];
7573        R[t] = SignExtend(MemU[address,1], 32);
7574        if wback then R[n] = offset_addr;
7575#endif
7576
7577  bool success = false;
7578
7579  if (ConditionPassed(opcode)) {
7580    uint32_t t;
7581    uint32_t n;
7582    uint32_t imm32;
7583    bool index;
7584    bool add;
7585    bool wback;
7586
7587    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7588    switch (encoding) {
7589    case eEncodingT1:
7590      // if Rt == '1111' then SEE PLI;
7591      // if Rn == '1111' then SEE LDRSB (literal);
7592      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7593      t = Bits32(opcode, 15, 12);
7594      n = Bits32(opcode, 19, 16);
7595      imm32 = Bits32(opcode, 11, 0);
7596
7597      // index = TRUE; add = TRUE; wback = FALSE;
7598      index = true;
7599      add = true;
7600      wback = false;
7601
7602      // if t == 13 then UNPREDICTABLE;
7603      if (t == 13)
7604        return false;
7605
7606      break;
7607
7608    case eEncodingT2:
7609      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7610      // if Rn == '1111' then SEE LDRSB (literal);
7611      // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7612      // if P == '0' && W == '0' then UNDEFINED;
7613      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7614        return false;
7615
7616      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7617      t = Bits32(opcode, 15, 12);
7618      n = Bits32(opcode, 19, 16);
7619      imm32 = Bits32(opcode, 7, 0);
7620
7621      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7622      index = BitIsSet(opcode, 10);
7623      add = BitIsSet(opcode, 9);
7624      wback = BitIsSet(opcode, 8);
7625
7626      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7627      if (((t == 13) ||
7628           ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7629                          BitIsSet(opcode, 8)))) ||
7630          (wback && (n == t)))
7631        return false;
7632
7633      break;
7634
7635    case eEncodingA1: {
7636      // if Rn == '1111' then SEE LDRSB (literal);
7637      // if P == '0' && W == '1' then SEE LDRSBT;
7638      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7639      t = Bits32(opcode, 15, 12);
7640      n = Bits32(opcode, 19, 16);
7641
7642      uint32_t imm4H = Bits32(opcode, 11, 8);
7643      uint32_t imm4L = Bits32(opcode, 3, 0);
7644      imm32 = (imm4H << 4) | imm4L;
7645
7646      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7647      // (W == '1');
7648      index = BitIsSet(opcode, 24);
7649      add = BitIsSet(opcode, 23);
7650      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7651
7652      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7653      if ((t == 15) || (wback && (n == t)))
7654        return false;
7655
7656      break;
7657    }
7658
7659    default:
7660      return false;
7661    }
7662
7663    uint64_t Rn = ReadCoreReg(n, &success);
7664    if (!success)
7665      return false;
7666
7667    addr_t offset_addr;
7668    addr_t address;
7669
7670    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7671    if (add)
7672      offset_addr = Rn + imm32;
7673    else
7674      offset_addr = Rn - imm32;
7675
7676    // address = if index then offset_addr else R[n];
7677    if (index)
7678      address = offset_addr;
7679    else
7680      address = Rn;
7681
7682    // R[t] = SignExtend(MemU[address,1], 32);
7683    RegisterInfo base_reg;
7684    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7685
7686    EmulateInstruction::Context context;
7687    context.type = eContextRegisterLoad;
7688    context.SetRegisterPlusOffset(base_reg, address - Rn);
7689
7690    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7691    if (!success)
7692      return false;
7693
7694    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7695    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7696                               (uint64_t)signed_data))
7697      return false;
7698
7699    // if wback then R[n] = offset_addr;
7700    if (wback) {
7701      context.type = eContextAdjustBaseRegister;
7702      context.SetAddress(offset_addr);
7703      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7704                                 offset_addr))
7705        return false;
7706    }
7707  }
7708
7709  return true;
7710}
7711
7712// LDRSB (literal) calculates an address from the PC value and an immediate
7713// offset, loads a byte from memory,
7714// sign-extends it to form a 32-bit word, and writes tit to a register.
7715bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7716                                                const ARMEncoding encoding) {
7717#if 0
7718    if ConditionPassed() then
7719        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7720        base = Align(PC,4);
7721        address = if add then (base + imm32) else (base - imm32);
7722        R[t] = SignExtend(MemU[address,1], 32);
7723#endif
7724
7725  bool success = false;
7726
7727  if (ConditionPassed(opcode)) {
7728    uint32_t t;
7729    uint32_t imm32;
7730    bool add;
7731
7732    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7733    switch (encoding) {
7734    case eEncodingT1:
7735      // if Rt == '1111' then SEE PLI;
7736      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7737      t = Bits32(opcode, 15, 12);
7738      imm32 = Bits32(opcode, 11, 0);
7739      add = BitIsSet(opcode, 23);
7740
7741      // if t == 13 then UNPREDICTABLE;
7742      if (t == 13)
7743        return false;
7744
7745      break;
7746
7747    case eEncodingA1: {
7748      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7749      t = Bits32(opcode, 15, 12);
7750      uint32_t imm4H = Bits32(opcode, 11, 8);
7751      uint32_t imm4L = Bits32(opcode, 3, 0);
7752      imm32 = (imm4H << 4) | imm4L;
7753      add = BitIsSet(opcode, 23);
7754
7755      // if t == 15 then UNPREDICTABLE;
7756      if (t == 15)
7757        return false;
7758
7759      break;
7760    }
7761
7762    default:
7763      return false;
7764    }
7765
7766    // base = Align(PC,4);
7767    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7768    if (!success)
7769      return false;
7770    uint64_t base = AlignPC(pc_value);
7771
7772    // address = if add then (base + imm32) else (base - imm32);
7773    addr_t address;
7774    if (add)
7775      address = base + imm32;
7776    else
7777      address = base - imm32;
7778
7779    // R[t] = SignExtend(MemU[address,1], 32);
7780    RegisterInfo base_reg;
7781    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7782
7783    EmulateInstruction::Context context;
7784    context.type = eContextRegisterLoad;
7785    context.SetRegisterPlusOffset(base_reg, address - base);
7786
7787    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7788    if (!success)
7789      return false;
7790
7791    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7792    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7793                               (uint64_t)signed_data))
7794      return false;
7795  }
7796  return true;
7797}
7798
7799// LDRSB (register) calculates an address from a base register value and an
7800// offset register value, loadsa byte from
7801// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7802// The offset register value can be
7803// shifted left by 0, 1, 2, or 3 bits.
7804bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7805                                                 const ARMEncoding encoding) {
7806#if 0
7807    if ConditionPassed() then
7808        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7809        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7810        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7811        address = if index then offset_addr else R[n];
7812        R[t] = SignExtend(MemU[address,1], 32);
7813        if wback then R[n] = offset_addr;
7814#endif
7815
7816  bool success = false;
7817
7818  if (ConditionPassed(opcode)) {
7819    uint32_t t;
7820    uint32_t n;
7821    uint32_t m;
7822    bool index;
7823    bool add;
7824    bool wback;
7825    ARM_ShifterType shift_t;
7826    uint32_t shift_n;
7827
7828    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7829    switch (encoding) {
7830    case eEncodingT1:
7831      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7832      t = Bits32(opcode, 2, 0);
7833      n = Bits32(opcode, 5, 3);
7834      m = Bits32(opcode, 8, 6);
7835
7836      // index = TRUE; add = TRUE; wback = FALSE;
7837      index = true;
7838      add = true;
7839      wback = false;
7840
7841      // (shift_t, shift_n) = (SRType_LSL, 0);
7842      shift_t = SRType_LSL;
7843      shift_n = 0;
7844
7845      break;
7846
7847    case eEncodingT2:
7848      // if Rt == '1111' then SEE PLI;
7849      // if Rn == '1111' then SEE LDRSB (literal);
7850      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7851      t = Bits32(opcode, 15, 12);
7852      n = Bits32(opcode, 19, 16);
7853      m = Bits32(opcode, 3, 0);
7854
7855      // index = TRUE; add = TRUE; wback = FALSE;
7856      index = true;
7857      add = true;
7858      wback = false;
7859
7860      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7861      shift_t = SRType_LSL;
7862      shift_n = Bits32(opcode, 5, 4);
7863
7864      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7865      if ((t == 13) || BadReg(m))
7866        return false;
7867      break;
7868
7869    case eEncodingA1:
7870      // if P == '0' && W == '1' then SEE LDRSBT;
7871      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7872      t = Bits32(opcode, 15, 12);
7873      n = Bits32(opcode, 19, 16);
7874      m = Bits32(opcode, 3, 0);
7875
7876      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7877      // (W == '1');
7878      index = BitIsSet(opcode, 24);
7879      add = BitIsSet(opcode, 23);
7880      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7881
7882      // (shift_t, shift_n) = (SRType_LSL, 0);
7883      shift_t = SRType_LSL;
7884      shift_n = 0;
7885
7886      // if t == 15 || m == 15 then UNPREDICTABLE;
7887      if ((t == 15) || (m == 15))
7888        return false;
7889
7890      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7891      if (wback && ((n == 15) || (n == t)))
7892        return false;
7893      break;
7894
7895    default:
7896      return false;
7897    }
7898
7899    uint64_t Rm =
7900        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7901    if (!success)
7902      return false;
7903
7904    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7905    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7906    if (!success)
7907      return false;
7908
7909    addr_t offset_addr;
7910    addr_t address;
7911
7912    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7913    uint64_t Rn =
7914        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7915    if (!success)
7916      return false;
7917
7918    if (add)
7919      offset_addr = Rn + offset;
7920    else
7921      offset_addr = Rn - offset;
7922
7923    // address = if index then offset_addr else R[n];
7924    if (index)
7925      address = offset_addr;
7926    else
7927      address = Rn;
7928
7929    // R[t] = SignExtend(MemU[address,1], 32);
7930    RegisterInfo base_reg;
7931    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7932    RegisterInfo offset_reg;
7933    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7934
7935    EmulateInstruction::Context context;
7936    context.type = eContextRegisterLoad;
7937    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7938
7939    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7940    if (!success)
7941      return false;
7942
7943    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7944    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7945                               (uint64_t)signed_data))
7946      return false;
7947
7948    // if wback then R[n] = offset_addr;
7949    if (wback) {
7950      context.type = eContextAdjustBaseRegister;
7951      context.SetAddress(offset_addr);
7952      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7953                                 offset_addr))
7954        return false;
7955    }
7956  }
7957  return true;
7958}
7959
7960// LDRSH (immediate) calculates an address from a base register value and an
7961// immediate offset, loads a halfword from
7962// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7963// It can use offset, post-indexed, or
7964// pre-indexed addressing.
7965bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7966                                                  const ARMEncoding encoding) {
7967#if 0
7968    if ConditionPassed() then
7969        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7970        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7971        address = if index then offset_addr else R[n];
7972        data = MemU[address,2];
7973        if wback then R[n] = offset_addr;
7974        if UnalignedSupport() || address<0> = '0' then
7975            R[t] = SignExtend(data, 32);
7976        else // Can only apply before ARMv7
7977            R[t] = bits(32) UNKNOWN;
7978#endif
7979
7980  bool success = false;
7981
7982  if (ConditionPassed(opcode)) {
7983    uint32_t t;
7984    uint32_t n;
7985    uint32_t imm32;
7986    bool index;
7987    bool add;
7988    bool wback;
7989
7990    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7991    switch (encoding) {
7992    case eEncodingT1:
7993      // if Rn == '1111' then SEE LDRSH (literal);
7994      // if Rt == '1111' then SEE "Unallocated memory hints";
7995      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7996      t = Bits32(opcode, 15, 12);
7997      n = Bits32(opcode, 19, 16);
7998      imm32 = Bits32(opcode, 11, 0);
7999
8000      // index = TRUE; add = TRUE; wback = FALSE;
8001      index = true;
8002      add = true;
8003      wback = false;
8004
8005      // if t == 13 then UNPREDICTABLE;
8006      if (t == 13)
8007        return false;
8008
8009      break;
8010
8011    case eEncodingT2:
8012      // if Rn == '1111' then SEE LDRSH (literal);
8013      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
8014      // "Unallocated memory hints";
8015      // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
8016      // if P == '0' && W == '0' then UNDEFINED;
8017      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
8018        return false;
8019
8020      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
8021      t = Bits32(opcode, 15, 12);
8022      n = Bits32(opcode, 19, 16);
8023      imm32 = Bits32(opcode, 7, 0);
8024
8025      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
8026      index = BitIsSet(opcode, 10);
8027      add = BitIsSet(opcode, 9);
8028      wback = BitIsSet(opcode, 8);
8029
8030      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
8031      if (BadReg(t) || (wback && (n == t)))
8032        return false;
8033
8034      break;
8035
8036    case eEncodingA1: {
8037      // if Rn == '1111' then SEE LDRSH (literal);
8038      // if P == '0' && W == '1' then SEE LDRSHT;
8039      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
8040      t = Bits32(opcode, 15, 12);
8041      n = Bits32(opcode, 19, 16);
8042      uint32_t imm4H = Bits32(opcode, 11, 8);
8043      uint32_t imm4L = Bits32(opcode, 3, 0);
8044      imm32 = (imm4H << 4) | imm4L;
8045
8046      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
8047      // (W == '1');
8048      index = BitIsSet(opcode, 24);
8049      add = BitIsSet(opcode, 23);
8050      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8051
8052      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
8053      if ((t == 15) || (wback && (n == t)))
8054        return false;
8055
8056      break;
8057    }
8058
8059    default:
8060      return false;
8061    }
8062
8063    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8064    uint64_t Rn =
8065        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8066    if (!success)
8067      return false;
8068
8069    addr_t offset_addr;
8070    if (add)
8071      offset_addr = Rn + imm32;
8072    else
8073      offset_addr = Rn - imm32;
8074
8075    // address = if index then offset_addr else R[n];
8076    addr_t address;
8077    if (index)
8078      address = offset_addr;
8079    else
8080      address = Rn;
8081
8082    // data = MemU[address,2];
8083    RegisterInfo base_reg;
8084    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8085
8086    EmulateInstruction::Context context;
8087    context.type = eContextRegisterLoad;
8088    context.SetRegisterPlusOffset(base_reg, address - Rn);
8089
8090    uint64_t data = MemURead(context, address, 2, 0, &success);
8091    if (!success)
8092      return false;
8093
8094    // if wback then R[n] = offset_addr;
8095    if (wback) {
8096      context.type = eContextAdjustBaseRegister;
8097      context.SetAddress(offset_addr);
8098      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8099                                 offset_addr))
8100        return false;
8101    }
8102
8103    // if UnalignedSupport() || address<0> = '0' then
8104    if (UnalignedSupport() || BitIsClear(address, 0)) {
8105      // R[t] = SignExtend(data, 32);
8106      int64_t signed_data = llvm::SignExtend64<16>(data);
8107      context.type = eContextRegisterLoad;
8108      context.SetRegisterPlusOffset(base_reg, address - Rn);
8109      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8110                                 (uint64_t)signed_data))
8111        return false;
8112    } else // Can only apply before ARMv7
8113    {
8114      // R[t] = bits(32) UNKNOWN;
8115      WriteBits32Unknown(t);
8116    }
8117  }
8118  return true;
8119}
8120
8121// LDRSH (literal) calculates an address from the PC value and an immediate
8122// offset, loads a halfword from memory,
8123// sign-extends it to from a 32-bit word, and writes it to a register.
8124bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8125                                                const ARMEncoding encoding) {
8126#if 0
8127    if ConditionPassed() then
8128        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8129        base = Align(PC,4);
8130        address = if add then (base + imm32) else (base - imm32);
8131        data = MemU[address,2];
8132        if UnalignedSupport() || address<0> = '0' then
8133            R[t] = SignExtend(data, 32);
8134        else // Can only apply before ARMv7
8135            R[t] = bits(32) UNKNOWN;
8136#endif
8137
8138  bool success = false;
8139
8140  if (ConditionPassed(opcode)) {
8141    uint32_t t;
8142    uint32_t imm32;
8143    bool add;
8144
8145    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8146    switch (encoding) {
8147    case eEncodingT1:
8148      // if Rt == '1111' then SEE "Unallocated memory hints";
8149      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8150      t = Bits32(opcode, 15, 12);
8151      imm32 = Bits32(opcode, 11, 0);
8152      add = BitIsSet(opcode, 23);
8153
8154      // if t == 13 then UNPREDICTABLE;
8155      if (t == 13)
8156        return false;
8157
8158      break;
8159
8160    case eEncodingA1: {
8161      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8162      t = Bits32(opcode, 15, 12);
8163      uint32_t imm4H = Bits32(opcode, 11, 8);
8164      uint32_t imm4L = Bits32(opcode, 3, 0);
8165      imm32 = (imm4H << 4) | imm4L;
8166      add = BitIsSet(opcode, 23);
8167
8168      // if t == 15 then UNPREDICTABLE;
8169      if (t == 15)
8170        return false;
8171
8172      break;
8173    }
8174    default:
8175      return false;
8176    }
8177
8178    // base = Align(PC,4);
8179    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8180    if (!success)
8181      return false;
8182
8183    uint64_t base = AlignPC(pc_value);
8184
8185    addr_t address;
8186    // address = if add then (base + imm32) else (base - imm32);
8187    if (add)
8188      address = base + imm32;
8189    else
8190      address = base - imm32;
8191
8192    // data = MemU[address,2];
8193    RegisterInfo base_reg;
8194    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8195
8196    EmulateInstruction::Context context;
8197    context.type = eContextRegisterLoad;
8198    context.SetRegisterPlusOffset(base_reg, imm32);
8199
8200    uint64_t data = MemURead(context, address, 2, 0, &success);
8201    if (!success)
8202      return false;
8203
8204    // if UnalignedSupport() || address<0> = '0' then
8205    if (UnalignedSupport() || BitIsClear(address, 0)) {
8206      // R[t] = SignExtend(data, 32);
8207      int64_t signed_data = llvm::SignExtend64<16>(data);
8208      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8209                                 (uint64_t)signed_data))
8210        return false;
8211    } else // Can only apply before ARMv7
8212    {
8213      // R[t] = bits(32) UNKNOWN;
8214      WriteBits32Unknown(t);
8215    }
8216  }
8217  return true;
8218}
8219
8220// LDRSH (register) calculates an address from a base register value and an
8221// offset register value, loads a halfword
8222// from memory, sign-extends it to form a 32-bit word, and writes it to a
8223// register.  The offset register value can be
8224// shifted left by 0, 1, 2, or 3 bits.
8225bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8226                                                 const ARMEncoding encoding) {
8227#if 0
8228    if ConditionPassed() then
8229        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8230        offset = Shift(R[m], shift_t, shift_n, APSR.C);
8231        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8232        address = if index then offset_addr else R[n];
8233        data = MemU[address,2];
8234        if wback then R[n] = offset_addr;
8235        if UnalignedSupport() || address<0> = '0' then
8236            R[t] = SignExtend(data, 32);
8237        else // Can only apply before ARMv7
8238            R[t] = bits(32) UNKNOWN;
8239#endif
8240
8241  bool success = false;
8242
8243  if (ConditionPassed(opcode)) {
8244    uint32_t t;
8245    uint32_t n;
8246    uint32_t m;
8247    bool index;
8248    bool add;
8249    bool wback;
8250    ARM_ShifterType shift_t;
8251    uint32_t shift_n;
8252
8253    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8254    switch (encoding) {
8255    case eEncodingT1:
8256      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8257      // in ThumbEE";
8258      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8259      t = Bits32(opcode, 2, 0);
8260      n = Bits32(opcode, 5, 3);
8261      m = Bits32(opcode, 8, 6);
8262
8263      // index = TRUE; add = TRUE; wback = FALSE;
8264      index = true;
8265      add = true;
8266      wback = false;
8267
8268      // (shift_t, shift_n) = (SRType_LSL, 0);
8269      shift_t = SRType_LSL;
8270      shift_n = 0;
8271
8272      break;
8273
8274    case eEncodingT2:
8275      // if Rn == '1111' then SEE LDRSH (literal);
8276      // if Rt == '1111' then SEE "Unallocated memory hints";
8277      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8278      t = Bits32(opcode, 15, 12);
8279      n = Bits32(opcode, 19, 16);
8280      m = Bits32(opcode, 3, 0);
8281
8282      // index = TRUE; add = TRUE; wback = FALSE;
8283      index = true;
8284      add = true;
8285      wback = false;
8286
8287      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8288      shift_t = SRType_LSL;
8289      shift_n = Bits32(opcode, 5, 4);
8290
8291      // if t == 13 || BadReg(m) then UNPREDICTABLE;
8292      if ((t == 13) || BadReg(m))
8293        return false;
8294
8295      break;
8296
8297    case eEncodingA1:
8298      // if P == '0' && W == '1' then SEE LDRSHT;
8299      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8300      t = Bits32(opcode, 15, 12);
8301      n = Bits32(opcode, 19, 16);
8302      m = Bits32(opcode, 3, 0);
8303
8304      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
8305      // (W == '1');
8306      index = BitIsSet(opcode, 24);
8307      add = BitIsSet(opcode, 23);
8308      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8309
8310      // (shift_t, shift_n) = (SRType_LSL, 0);
8311      shift_t = SRType_LSL;
8312      shift_n = 0;
8313
8314      // if t == 15 || m == 15 then UNPREDICTABLE;
8315      if ((t == 15) || (m == 15))
8316        return false;
8317
8318      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8319      if (wback && ((n == 15) || (n == t)))
8320        return false;
8321
8322      break;
8323
8324    default:
8325      return false;
8326    }
8327
8328    uint64_t Rm =
8329        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8330    if (!success)
8331      return false;
8332
8333    uint64_t Rn =
8334        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8335    if (!success)
8336      return false;
8337
8338    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8339    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8340    if (!success)
8341      return false;
8342
8343    addr_t offset_addr;
8344    addr_t address;
8345
8346    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8347    if (add)
8348      offset_addr = Rn + offset;
8349    else
8350      offset_addr = Rn - offset;
8351
8352    // address = if index then offset_addr else R[n];
8353    if (index)
8354      address = offset_addr;
8355    else
8356      address = Rn;
8357
8358    // data = MemU[address,2];
8359    RegisterInfo base_reg;
8360    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8361
8362    RegisterInfo offset_reg;
8363    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8364
8365    EmulateInstruction::Context context;
8366    context.type = eContextRegisterLoad;
8367    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8368
8369    uint64_t data = MemURead(context, address, 2, 0, &success);
8370    if (!success)
8371      return false;
8372
8373    // if wback then R[n] = offset_addr;
8374    if (wback) {
8375      context.type = eContextAdjustBaseRegister;
8376      context.SetAddress(offset_addr);
8377      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8378                                 offset_addr))
8379        return false;
8380    }
8381
8382    // if UnalignedSupport() || address<0> = '0' then
8383    if (UnalignedSupport() || BitIsClear(address, 0)) {
8384      // R[t] = SignExtend(data, 32);
8385      context.type = eContextRegisterLoad;
8386      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8387
8388      int64_t signed_data = llvm::SignExtend64<16>(data);
8389      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8390                                 (uint64_t)signed_data))
8391        return false;
8392    } else // Can only apply before ARMv7
8393    {
8394      // R[t] = bits(32) UNKNOWN;
8395      WriteBits32Unknown(t);
8396    }
8397  }
8398  return true;
8399}
8400
8401// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8402// writes the result to the destination
8403// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8404// extracting the 8-bit value.
8405bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8406                                        const ARMEncoding encoding) {
8407#if 0
8408    if ConditionPassed() then
8409        EncodingSpecificOperations();
8410        rotated = ROR(R[m], rotation);
8411        R[d] = SignExtend(rotated<7:0>, 32);
8412#endif
8413
8414  bool success = false;
8415
8416  if (ConditionPassed(opcode)) {
8417    uint32_t d;
8418    uint32_t m;
8419    uint32_t rotation;
8420
8421    // EncodingSpecificOperations();
8422    switch (encoding) {
8423    case eEncodingT1:
8424      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8425      d = Bits32(opcode, 2, 0);
8426      m = Bits32(opcode, 5, 3);
8427      rotation = 0;
8428
8429      break;
8430
8431    case eEncodingT2:
8432      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8433      d = Bits32(opcode, 11, 8);
8434      m = Bits32(opcode, 3, 0);
8435      rotation = Bits32(opcode, 5, 4) << 3;
8436
8437      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8438      if (BadReg(d) || BadReg(m))
8439        return false;
8440
8441      break;
8442
8443    case eEncodingA1:
8444      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8445      d = Bits32(opcode, 15, 12);
8446      m = Bits32(opcode, 3, 0);
8447      rotation = Bits32(opcode, 11, 10) << 3;
8448
8449      // if d == 15 || m == 15 then UNPREDICTABLE;
8450      if ((d == 15) || (m == 15))
8451        return false;
8452
8453      break;
8454
8455    default:
8456      return false;
8457    }
8458
8459    uint64_t Rm =
8460        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8461    if (!success)
8462      return false;
8463
8464    // rotated = ROR(R[m], rotation);
8465    uint64_t rotated = ROR(Rm, rotation, &success);
8466    if (!success)
8467      return false;
8468
8469    // R[d] = SignExtend(rotated<7:0>, 32);
8470    int64_t data = llvm::SignExtend64<8>(rotated);
8471
8472    RegisterInfo source_reg;
8473    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8474
8475    EmulateInstruction::Context context;
8476    context.type = eContextRegisterLoad;
8477    context.SetRegister(source_reg);
8478
8479    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8480                               (uint64_t)data))
8481      return false;
8482  }
8483  return true;
8484}
8485
8486// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8487// writes the result to the destination
8488// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8489// extracting the 16-bit value.
8490bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8491                                        const ARMEncoding encoding) {
8492#if 0
8493    if ConditionPassed() then
8494        EncodingSpecificOperations();
8495        rotated = ROR(R[m], rotation);
8496        R[d] = SignExtend(rotated<15:0>, 32);
8497#endif
8498
8499  bool success = false;
8500
8501  if (ConditionPassed(opcode)) {
8502    uint32_t d;
8503    uint32_t m;
8504    uint32_t rotation;
8505
8506    // EncodingSpecificOperations();
8507    switch (encoding) {
8508    case eEncodingT1:
8509      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8510      d = Bits32(opcode, 2, 0);
8511      m = Bits32(opcode, 5, 3);
8512      rotation = 0;
8513
8514      break;
8515
8516    case eEncodingT2:
8517      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8518      d = Bits32(opcode, 11, 8);
8519      m = Bits32(opcode, 3, 0);
8520      rotation = Bits32(opcode, 5, 4) << 3;
8521
8522      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8523      if (BadReg(d) || BadReg(m))
8524        return false;
8525
8526      break;
8527
8528    case eEncodingA1:
8529      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8530      d = Bits32(opcode, 15, 12);
8531      m = Bits32(opcode, 3, 0);
8532      rotation = Bits32(opcode, 11, 10) << 3;
8533
8534      // if d == 15 || m == 15 then UNPREDICTABLE;
8535      if ((d == 15) || (m == 15))
8536        return false;
8537
8538      break;
8539
8540    default:
8541      return false;
8542    }
8543
8544    uint64_t Rm =
8545        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8546    if (!success)
8547      return false;
8548
8549    // rotated = ROR(R[m], rotation);
8550    uint64_t rotated = ROR(Rm, rotation, &success);
8551    if (!success)
8552      return false;
8553
8554    // R[d] = SignExtend(rotated<15:0>, 32);
8555    RegisterInfo source_reg;
8556    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8557
8558    EmulateInstruction::Context context;
8559    context.type = eContextRegisterLoad;
8560    context.SetRegister(source_reg);
8561
8562    int64_t data = llvm::SignExtend64<16>(rotated);
8563    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8564                               (uint64_t)data))
8565      return false;
8566  }
8567
8568  return true;
8569}
8570
8571// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
8572// writes the result to the destination
8573// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8574// extracting the 8-bit value.
8575bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8576                                        const ARMEncoding encoding) {
8577#if 0
8578    if ConditionPassed() then
8579        EncodingSpecificOperations();
8580        rotated = ROR(R[m], rotation);
8581        R[d] = ZeroExtend(rotated<7:0>, 32);
8582#endif
8583
8584  bool success = false;
8585
8586  if (ConditionPassed(opcode)) {
8587    uint32_t d;
8588    uint32_t m;
8589    uint32_t rotation;
8590
8591    // EncodingSpecificOperations();
8592    switch (encoding) {
8593    case eEncodingT1:
8594      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8595      d = Bits32(opcode, 2, 0);
8596      m = Bits32(opcode, 5, 3);
8597      rotation = 0;
8598
8599      break;
8600
8601    case eEncodingT2:
8602      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8603      d = Bits32(opcode, 11, 8);
8604      m = Bits32(opcode, 3, 0);
8605      rotation = Bits32(opcode, 5, 4) << 3;
8606
8607      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8608      if (BadReg(d) || BadReg(m))
8609        return false;
8610
8611      break;
8612
8613    case eEncodingA1:
8614      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8615      d = Bits32(opcode, 15, 12);
8616      m = Bits32(opcode, 3, 0);
8617      rotation = Bits32(opcode, 11, 10) << 3;
8618
8619      // if d == 15 || m == 15 then UNPREDICTABLE;
8620      if ((d == 15) || (m == 15))
8621        return false;
8622
8623      break;
8624
8625    default:
8626      return false;
8627    }
8628
8629    uint64_t Rm =
8630        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8631    if (!success)
8632      return false;
8633
8634    // rotated = ROR(R[m], rotation);
8635    uint64_t rotated = ROR(Rm, rotation, &success);
8636    if (!success)
8637      return false;
8638
8639    // R[d] = ZeroExtend(rotated<7:0>, 32);
8640    RegisterInfo source_reg;
8641    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8642
8643    EmulateInstruction::Context context;
8644    context.type = eContextRegisterLoad;
8645    context.SetRegister(source_reg);
8646
8647    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8648                               Bits32(rotated, 7, 0)))
8649      return false;
8650  }
8651  return true;
8652}
8653
8654// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8655// writes the result to the destination
8656// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8657// extracting the 16-bit value.
8658bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8659                                        const ARMEncoding encoding) {
8660#if 0
8661    if ConditionPassed() then
8662        EncodingSpecificOperations();
8663        rotated = ROR(R[m], rotation);
8664        R[d] = ZeroExtend(rotated<15:0>, 32);
8665#endif
8666
8667  bool success = false;
8668
8669  if (ConditionPassed(opcode)) {
8670    uint32_t d;
8671    uint32_t m;
8672    uint32_t rotation;
8673
8674    switch (encoding) {
8675    case eEncodingT1:
8676      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8677      d = Bits32(opcode, 2, 0);
8678      m = Bits32(opcode, 5, 3);
8679      rotation = 0;
8680
8681      break;
8682
8683    case eEncodingT2:
8684      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8685      d = Bits32(opcode, 11, 8);
8686      m = Bits32(opcode, 3, 0);
8687      rotation = Bits32(opcode, 5, 4) << 3;
8688
8689      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8690      if (BadReg(d) || BadReg(m))
8691        return false;
8692
8693      break;
8694
8695    case eEncodingA1:
8696      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8697      d = Bits32(opcode, 15, 12);
8698      m = Bits32(opcode, 3, 0);
8699      rotation = Bits32(opcode, 11, 10) << 3;
8700
8701      // if d == 15 || m == 15 then UNPREDICTABLE;
8702      if ((d == 15) || (m == 15))
8703        return false;
8704
8705      break;
8706
8707    default:
8708      return false;
8709    }
8710
8711    uint64_t Rm =
8712        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8713    if (!success)
8714      return false;
8715
8716    // rotated = ROR(R[m], rotation);
8717    uint64_t rotated = ROR(Rm, rotation, &success);
8718    if (!success)
8719      return false;
8720
8721    // R[d] = ZeroExtend(rotated<15:0>, 32);
8722    RegisterInfo source_reg;
8723    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8724
8725    EmulateInstruction::Context context;
8726    context.type = eContextRegisterLoad;
8727    context.SetRegister(source_reg);
8728
8729    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8730                               Bits32(rotated, 15, 0)))
8731      return false;
8732  }
8733  return true;
8734}
8735
8736// RFE (Return From Exception) loads the PC and the CPSR from the word at the
8737// specified address and the following
8738// word respectively.
8739bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8740                                       const ARMEncoding encoding) {
8741#if 0
8742    if ConditionPassed() then
8743        EncodingSpecificOperations();
8744        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8745            UNPREDICTABLE;
8746        else
8747            address = if increment then R[n] else R[n]-8;
8748            if wordhigher then address = address+4;
8749            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8750            BranchWritePC(MemA[address,4]);
8751            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8752#endif
8753
8754  bool success = false;
8755
8756  if (ConditionPassed(opcode)) {
8757    uint32_t n;
8758    bool wback;
8759    bool increment;
8760    bool wordhigher;
8761
8762    // EncodingSpecificOperations();
8763    switch (encoding) {
8764    case eEncodingT1:
8765      // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8766      // FALSE;
8767      n = Bits32(opcode, 19, 16);
8768      wback = BitIsSet(opcode, 21);
8769      increment = false;
8770      wordhigher = false;
8771
8772      // if n == 15 then UNPREDICTABLE;
8773      if (n == 15)
8774        return false;
8775
8776      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8777      if (InITBlock() && !LastInITBlock())
8778        return false;
8779
8780      break;
8781
8782    case eEncodingT2:
8783      // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8784      n = Bits32(opcode, 19, 16);
8785      wback = BitIsSet(opcode, 21);
8786      increment = true;
8787      wordhigher = false;
8788
8789      // if n == 15 then UNPREDICTABLE;
8790      if (n == 15)
8791        return false;
8792
8793      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8794      if (InITBlock() && !LastInITBlock())
8795        return false;
8796
8797      break;
8798
8799    case eEncodingA1:
8800      // n = UInt(Rn);
8801      n = Bits32(opcode, 19, 16);
8802
8803      // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8804      wback = BitIsSet(opcode, 21);
8805      increment = BitIsSet(opcode, 23);
8806      wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8807
8808      // if n == 15 then UNPREDICTABLE;
8809      if (n == 15)
8810        return false;
8811
8812      break;
8813
8814    default:
8815      return false;
8816    }
8817
8818    // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8819    // then
8820    if (!CurrentModeIsPrivileged())
8821      // UNPREDICTABLE;
8822      return false;
8823    else {
8824      uint64_t Rn =
8825          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8826      if (!success)
8827        return false;
8828
8829      addr_t address;
8830      // address = if increment then R[n] else R[n]-8;
8831      if (increment)
8832        address = Rn;
8833      else
8834        address = Rn - 8;
8835
8836      // if wordhigher then address = address+4;
8837      if (wordhigher)
8838        address = address + 4;
8839
8840      // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8841      RegisterInfo base_reg;
8842      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8843
8844      EmulateInstruction::Context context;
8845      context.type = eContextReturnFromException;
8846      context.SetRegisterPlusOffset(base_reg, address - Rn);
8847
8848      uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8849      if (!success)
8850        return false;
8851
8852      CPSRWriteByInstr(data, 15, true);
8853
8854      // BranchWritePC(MemA[address,4]);
8855      uint64_t data2 = MemARead(context, address, 4, 0, &success);
8856      if (!success)
8857        return false;
8858
8859      BranchWritePC(context, data2);
8860
8861      // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8862      if (wback) {
8863        context.type = eContextAdjustBaseRegister;
8864        if (increment) {
8865          context.SetOffset(8);
8866          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8867                                     Rn + 8))
8868            return false;
8869        } else {
8870          context.SetOffset(-8);
8871          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8872                                     Rn - 8))
8873            return false;
8874        }
8875      } // if wback
8876    }
8877  } // if ConditionPassed()
8878  return true;
8879}
8880
8881// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8882// register value and an immediate value,
8883// and writes the result to the destination register.  It can optionally update
8884// the condition flags based on
8885// the result.
8886bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8887                                          const ARMEncoding encoding) {
8888#if 0
8889    // ARM pseudo code...
8890    if ConditionPassed() then
8891        EncodingSpecificOperations();
8892        result = R[n] EOR imm32;
8893        if d == 15 then         // Can only occur for ARM encoding
8894            ALUWritePC(result); // setflags is always FALSE here
8895        else
8896            R[d] = result;
8897            if setflags then
8898                APSR.N = result<31>;
8899                APSR.Z = IsZeroBit(result);
8900                APSR.C = carry;
8901                // APSR.V unchanged
8902#endif
8903
8904  bool success = false;
8905
8906  if (ConditionPassed(opcode)) {
8907    uint32_t Rd, Rn;
8908    uint32_t
8909        imm32; // the immediate value to be ORed to the value obtained from Rn
8910    bool setflags;
8911    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8912    switch (encoding) {
8913    case eEncodingT1:
8914      Rd = Bits32(opcode, 11, 8);
8915      Rn = Bits32(opcode, 19, 16);
8916      setflags = BitIsSet(opcode, 20);
8917      imm32 = ThumbExpandImm_C(
8918          opcode, APSR_C,
8919          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8920      // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8921      if (Rd == 15 && setflags)
8922        return EmulateTEQImm(opcode, eEncodingT1);
8923      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8924        return false;
8925      break;
8926    case eEncodingA1:
8927      Rd = Bits32(opcode, 15, 12);
8928      Rn = Bits32(opcode, 19, 16);
8929      setflags = BitIsSet(opcode, 20);
8930      imm32 =
8931          ARMExpandImm_C(opcode, APSR_C,
8932                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8933
8934      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8935      // instructions;
8936      if (Rd == 15 && setflags)
8937        return EmulateSUBSPcLrEtc(opcode, encoding);
8938      break;
8939    default:
8940      return false;
8941    }
8942
8943    // Read the first operand.
8944    uint32_t val1 = ReadCoreReg(Rn, &success);
8945    if (!success)
8946      return false;
8947
8948    uint32_t result = val1 ^ imm32;
8949
8950    EmulateInstruction::Context context;
8951    context.type = EmulateInstruction::eContextImmediate;
8952    context.SetNoArgs();
8953
8954    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8955      return false;
8956  }
8957  return true;
8958}
8959
8960// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register
8961// value and an
8962// optionally-shifted register value, and writes the result to the destination
8963// register.
8964// It can optionally update the condition flags based on the result.
8965bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8966                                          const ARMEncoding encoding) {
8967#if 0
8968    // ARM pseudo code...
8969    if ConditionPassed() then
8970        EncodingSpecificOperations();
8971        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8972        result = R[n] EOR shifted;
8973        if d == 15 then         // Can only occur for ARM encoding
8974            ALUWritePC(result); // setflags is always FALSE here
8975        else
8976            R[d] = result;
8977            if setflags then
8978                APSR.N = result<31>;
8979                APSR.Z = IsZeroBit(result);
8980                APSR.C = carry;
8981                // APSR.V unchanged
8982#endif
8983
8984  bool success = false;
8985
8986  if (ConditionPassed(opcode)) {
8987    uint32_t Rd, Rn, Rm;
8988    ARM_ShifterType shift_t;
8989    uint32_t shift_n; // the shift applied to the value read from Rm
8990    bool setflags;
8991    uint32_t carry;
8992    switch (encoding) {
8993    case eEncodingT1:
8994      Rd = Rn = Bits32(opcode, 2, 0);
8995      Rm = Bits32(opcode, 5, 3);
8996      setflags = !InITBlock();
8997      shift_t = SRType_LSL;
8998      shift_n = 0;
8999      break;
9000    case eEncodingT2:
9001      Rd = Bits32(opcode, 11, 8);
9002      Rn = Bits32(opcode, 19, 16);
9003      Rm = Bits32(opcode, 3, 0);
9004      setflags = BitIsSet(opcode, 20);
9005      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9006      // if Rd == '1111' && S == '1' then SEE TEQ (register);
9007      if (Rd == 15 && setflags)
9008        return EmulateTEQReg(opcode, eEncodingT1);
9009      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
9010        return false;
9011      break;
9012    case eEncodingA1:
9013      Rd = Bits32(opcode, 15, 12);
9014      Rn = Bits32(opcode, 19, 16);
9015      Rm = Bits32(opcode, 3, 0);
9016      setflags = BitIsSet(opcode, 20);
9017      shift_n = DecodeImmShiftARM(opcode, shift_t);
9018
9019      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9020      // instructions;
9021      if (Rd == 15 && setflags)
9022        return EmulateSUBSPcLrEtc(opcode, encoding);
9023      break;
9024    default:
9025      return false;
9026    }
9027
9028    // Read the first operand.
9029    uint32_t val1 = ReadCoreReg(Rn, &success);
9030    if (!success)
9031      return false;
9032
9033    // Read the second operand.
9034    uint32_t val2 = ReadCoreReg(Rm, &success);
9035    if (!success)
9036      return false;
9037
9038    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9039    if (!success)
9040      return false;
9041    uint32_t result = val1 ^ shifted;
9042
9043    EmulateInstruction::Context context;
9044    context.type = EmulateInstruction::eContextImmediate;
9045    context.SetNoArgs();
9046
9047    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9048      return false;
9049  }
9050  return true;
9051}
9052
9053// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
9054// and an immediate value, and
9055// writes the result to the destination register.  It can optionally update the
9056// condition flags based
9057// on the result.
9058bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
9059                                          const ARMEncoding encoding) {
9060#if 0
9061    // ARM pseudo code...
9062    if ConditionPassed() then
9063        EncodingSpecificOperations();
9064        result = R[n] OR imm32;
9065        if d == 15 then         // Can only occur for ARM encoding
9066            ALUWritePC(result); // setflags is always FALSE here
9067        else
9068            R[d] = result;
9069            if setflags then
9070                APSR.N = result<31>;
9071                APSR.Z = IsZeroBit(result);
9072                APSR.C = carry;
9073                // APSR.V unchanged
9074#endif
9075
9076  bool success = false;
9077
9078  if (ConditionPassed(opcode)) {
9079    uint32_t Rd, Rn;
9080    uint32_t
9081        imm32; // the immediate value to be ORed to the value obtained from Rn
9082    bool setflags;
9083    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9084    switch (encoding) {
9085    case eEncodingT1:
9086      Rd = Bits32(opcode, 11, 8);
9087      Rn = Bits32(opcode, 19, 16);
9088      setflags = BitIsSet(opcode, 20);
9089      imm32 = ThumbExpandImm_C(
9090          opcode, APSR_C,
9091          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9092      // if Rn == '1111' then SEE MOV (immediate);
9093      if (Rn == 15)
9094        return EmulateMOVRdImm(opcode, eEncodingT2);
9095      if (BadReg(Rd) || Rn == 13)
9096        return false;
9097      break;
9098    case eEncodingA1:
9099      Rd = Bits32(opcode, 15, 12);
9100      Rn = Bits32(opcode, 19, 16);
9101      setflags = BitIsSet(opcode, 20);
9102      imm32 =
9103          ARMExpandImm_C(opcode, APSR_C,
9104                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9105
9106      if (Rd == 15 && setflags)
9107        return EmulateSUBSPcLrEtc(opcode, encoding);
9108      break;
9109    default:
9110      return false;
9111    }
9112
9113    // Read the first operand.
9114    uint32_t val1 = ReadCoreReg(Rn, &success);
9115    if (!success)
9116      return false;
9117
9118    uint32_t result = val1 | imm32;
9119
9120    EmulateInstruction::Context context;
9121    context.type = EmulateInstruction::eContextImmediate;
9122    context.SetNoArgs();
9123
9124    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9125      return false;
9126  }
9127  return true;
9128}
9129
9130// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9131// and an optionally-shifted register
9132// value, and writes the result to the destination register.  It can optionally
9133// update the condition flags based
9134// on the result.
9135bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9136                                          const ARMEncoding encoding) {
9137#if 0
9138    // ARM pseudo code...
9139    if ConditionPassed() then
9140        EncodingSpecificOperations();
9141        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9142        result = R[n] OR shifted;
9143        if d == 15 then         // Can only occur for ARM encoding
9144            ALUWritePC(result); // setflags is always FALSE here
9145        else
9146            R[d] = result;
9147            if setflags then
9148                APSR.N = result<31>;
9149                APSR.Z = IsZeroBit(result);
9150                APSR.C = carry;
9151                // APSR.V unchanged
9152#endif
9153
9154  bool success = false;
9155
9156  if (ConditionPassed(opcode)) {
9157    uint32_t Rd, Rn, Rm;
9158    ARM_ShifterType shift_t;
9159    uint32_t shift_n; // the shift applied to the value read from Rm
9160    bool setflags;
9161    uint32_t carry;
9162    switch (encoding) {
9163    case eEncodingT1:
9164      Rd = Rn = Bits32(opcode, 2, 0);
9165      Rm = Bits32(opcode, 5, 3);
9166      setflags = !InITBlock();
9167      shift_t = SRType_LSL;
9168      shift_n = 0;
9169      break;
9170    case eEncodingT2:
9171      Rd = Bits32(opcode, 11, 8);
9172      Rn = Bits32(opcode, 19, 16);
9173      Rm = Bits32(opcode, 3, 0);
9174      setflags = BitIsSet(opcode, 20);
9175      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9176      // if Rn == '1111' then SEE MOV (register);
9177      if (Rn == 15)
9178        return EmulateMOVRdRm(opcode, eEncodingT3);
9179      if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9180        return false;
9181      break;
9182    case eEncodingA1:
9183      Rd = Bits32(opcode, 15, 12);
9184      Rn = Bits32(opcode, 19, 16);
9185      Rm = Bits32(opcode, 3, 0);
9186      setflags = BitIsSet(opcode, 20);
9187      shift_n = DecodeImmShiftARM(opcode, shift_t);
9188
9189      if (Rd == 15 && setflags)
9190        return EmulateSUBSPcLrEtc(opcode, encoding);
9191      break;
9192    default:
9193      return false;
9194    }
9195
9196    // Read the first operand.
9197    uint32_t val1 = ReadCoreReg(Rn, &success);
9198    if (!success)
9199      return false;
9200
9201    // Read the second operand.
9202    uint32_t val2 = ReadCoreReg(Rm, &success);
9203    if (!success)
9204      return false;
9205
9206    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9207    if (!success)
9208      return false;
9209    uint32_t result = val1 | shifted;
9210
9211    EmulateInstruction::Context context;
9212    context.type = EmulateInstruction::eContextImmediate;
9213    context.SetNoArgs();
9214
9215    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9216      return false;
9217  }
9218  return true;
9219}
9220
9221// Reverse Subtract (immediate) subtracts a register value from an immediate
9222// value, and writes the result to
9223// the destination register. It can optionally update the condition flags based
9224// on the result.
9225bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9226                                          const ARMEncoding encoding) {
9227#if 0
9228    // ARM pseudo code...
9229    if ConditionPassed() then
9230        EncodingSpecificOperations();
9231        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9232        if d == 15 then         // Can only occur for ARM encoding
9233            ALUWritePC(result); // setflags is always FALSE here
9234        else
9235            R[d] = result;
9236            if setflags then
9237                APSR.N = result<31>;
9238                APSR.Z = IsZeroBit(result);
9239                APSR.C = carry;
9240                APSR.V = overflow;
9241#endif
9242
9243  bool success = false;
9244
9245  uint32_t Rd; // the destination register
9246  uint32_t Rn; // the first operand
9247  bool setflags;
9248  uint32_t
9249      imm32; // the immediate value to be added to the value obtained from Rn
9250  switch (encoding) {
9251  case eEncodingT1:
9252    Rd = Bits32(opcode, 2, 0);
9253    Rn = Bits32(opcode, 5, 3);
9254    setflags = !InITBlock();
9255    imm32 = 0;
9256    break;
9257  case eEncodingT2:
9258    Rd = Bits32(opcode, 11, 8);
9259    Rn = Bits32(opcode, 19, 16);
9260    setflags = BitIsSet(opcode, 20);
9261    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9262    if (BadReg(Rd) || BadReg(Rn))
9263      return false;
9264    break;
9265  case eEncodingA1:
9266    Rd = Bits32(opcode, 15, 12);
9267    Rn = Bits32(opcode, 19, 16);
9268    setflags = BitIsSet(opcode, 20);
9269    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9270
9271    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9272    // instructions;
9273    if (Rd == 15 && setflags)
9274      return EmulateSUBSPcLrEtc(opcode, encoding);
9275    break;
9276  default:
9277    return false;
9278  }
9279  // Read the register value from the operand register Rn.
9280  uint32_t reg_val = ReadCoreReg(Rn, &success);
9281  if (!success)
9282    return false;
9283
9284  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9285
9286  EmulateInstruction::Context context;
9287  context.type = EmulateInstruction::eContextImmediate;
9288  context.SetNoArgs();
9289
9290  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9291                                 res.carry_out, res.overflow))
9292    return false;
9293
9294  return true;
9295}
9296
9297// Reverse Subtract (register) subtracts a register value from an
9298// optionally-shifted register value, and writes the
9299// result to the destination register. It can optionally update the condition
9300// flags based on the result.
9301bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9302                                          const ARMEncoding encoding) {
9303#if 0
9304    // ARM pseudo code...
9305    if ConditionPassed() then
9306        EncodingSpecificOperations();
9307        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9308        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9309        if d == 15 then         // Can only occur for ARM encoding
9310            ALUWritePC(result); // setflags is always FALSE here
9311        else
9312            R[d] = result;
9313            if setflags then
9314                APSR.N = result<31>;
9315                APSR.Z = IsZeroBit(result);
9316                APSR.C = carry;
9317                APSR.V = overflow;
9318#endif
9319
9320  bool success = false;
9321
9322  uint32_t Rd; // the destination register
9323  uint32_t Rn; // the first operand
9324  uint32_t Rm; // the second operand
9325  bool setflags;
9326  ARM_ShifterType shift_t;
9327  uint32_t shift_n; // the shift applied to the value read from Rm
9328  switch (encoding) {
9329  case eEncodingT1:
9330    Rd = Bits32(opcode, 11, 8);
9331    Rn = Bits32(opcode, 19, 16);
9332    Rm = Bits32(opcode, 3, 0);
9333    setflags = BitIsSet(opcode, 20);
9334    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9335    // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9336    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9337      return false;
9338    break;
9339  case eEncodingA1:
9340    Rd = Bits32(opcode, 15, 12);
9341    Rn = Bits32(opcode, 19, 16);
9342    Rm = Bits32(opcode, 3, 0);
9343    setflags = BitIsSet(opcode, 20);
9344    shift_n = DecodeImmShiftARM(opcode, shift_t);
9345
9346    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9347    // instructions;
9348    if (Rd == 15 && setflags)
9349      return EmulateSUBSPcLrEtc(opcode, encoding);
9350    break;
9351  default:
9352    return false;
9353  }
9354  // Read the register value from register Rn.
9355  uint32_t val1 = ReadCoreReg(Rn, &success);
9356  if (!success)
9357    return false;
9358
9359  // Read the register value from register Rm.
9360  uint32_t val2 = ReadCoreReg(Rm, &success);
9361  if (!success)
9362    return false;
9363
9364  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9365  if (!success)
9366    return false;
9367  AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9368
9369  EmulateInstruction::Context context;
9370  context.type = EmulateInstruction::eContextImmediate;
9371  context.SetNoArgs();
9372  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9373                                 res.carry_out, res.overflow))
9374    return false;
9375
9376  return true;
9377}
9378
9379// Reverse Subtract with Carry (immediate) subtracts a register value and the
9380// value of NOT (Carry flag) from
9381// an immediate value, and writes the result to the destination register. It can
9382// optionally update the condition
9383// flags based on the result.
9384bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9385                                          const ARMEncoding encoding) {
9386#if 0
9387    // ARM pseudo code...
9388    if ConditionPassed() then
9389        EncodingSpecificOperations();
9390        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9391        if d == 15 then
9392            ALUWritePC(result); // setflags is always FALSE here
9393        else
9394            R[d] = result;
9395            if setflags then
9396                APSR.N = result<31>;
9397                APSR.Z = IsZeroBit(result);
9398                APSR.C = carry;
9399                APSR.V = overflow;
9400#endif
9401
9402  bool success = false;
9403
9404  uint32_t Rd; // the destination register
9405  uint32_t Rn; // the first operand
9406  bool setflags;
9407  uint32_t
9408      imm32; // the immediate value to be added to the value obtained from Rn
9409  switch (encoding) {
9410  case eEncodingA1:
9411    Rd = Bits32(opcode, 15, 12);
9412    Rn = Bits32(opcode, 19, 16);
9413    setflags = BitIsSet(opcode, 20);
9414    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9415
9416    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9417    // instructions;
9418    if (Rd == 15 && setflags)
9419      return EmulateSUBSPcLrEtc(opcode, encoding);
9420    break;
9421  default:
9422    return false;
9423  }
9424  // Read the register value from the operand register Rn.
9425  uint32_t reg_val = ReadCoreReg(Rn, &success);
9426  if (!success)
9427    return false;
9428
9429  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9430
9431  EmulateInstruction::Context context;
9432  context.type = EmulateInstruction::eContextImmediate;
9433  context.SetNoArgs();
9434
9435  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9436                                 res.carry_out, res.overflow))
9437    return false;
9438
9439  return true;
9440}
9441
9442// Reverse Subtract with Carry (register) subtracts a register value and the
9443// value of NOT (Carry flag) from an
9444// optionally-shifted register value, and writes the result to the destination
9445// register. It can optionally update the
9446// condition flags based on the result.
9447bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9448                                          const ARMEncoding encoding) {
9449#if 0
9450    // ARM pseudo code...
9451    if ConditionPassed() then
9452        EncodingSpecificOperations();
9453        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9454        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9455        if d == 15 then
9456            ALUWritePC(result); // setflags is always FALSE here
9457        else
9458            R[d] = result;
9459            if setflags then
9460                APSR.N = result<31>;
9461                APSR.Z = IsZeroBit(result);
9462                APSR.C = carry;
9463                APSR.V = overflow;
9464#endif
9465
9466  bool success = false;
9467
9468  uint32_t Rd; // the destination register
9469  uint32_t Rn; // the first operand
9470  uint32_t Rm; // the second operand
9471  bool setflags;
9472  ARM_ShifterType shift_t;
9473  uint32_t shift_n; // the shift applied to the value read from Rm
9474  switch (encoding) {
9475  case eEncodingA1:
9476    Rd = Bits32(opcode, 15, 12);
9477    Rn = Bits32(opcode, 19, 16);
9478    Rm = Bits32(opcode, 3, 0);
9479    setflags = BitIsSet(opcode, 20);
9480    shift_n = DecodeImmShiftARM(opcode, shift_t);
9481
9482    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9483    // instructions;
9484    if (Rd == 15 && setflags)
9485      return EmulateSUBSPcLrEtc(opcode, encoding);
9486    break;
9487  default:
9488    return false;
9489  }
9490  // Read the register value from register Rn.
9491  uint32_t val1 = ReadCoreReg(Rn, &success);
9492  if (!success)
9493    return false;
9494
9495  // Read the register value from register Rm.
9496  uint32_t val2 = ReadCoreReg(Rm, &success);
9497  if (!success)
9498    return false;
9499
9500  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9501  if (!success)
9502    return false;
9503  AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9504
9505  EmulateInstruction::Context context;
9506  context.type = EmulateInstruction::eContextImmediate;
9507  context.SetNoArgs();
9508  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9509                                 res.carry_out, res.overflow))
9510    return false;
9511
9512  return true;
9513}
9514
9515// Subtract with Carry (immediate) subtracts an immediate value and the value of
9516// NOT (Carry flag) from a register value, and writes the result to the
9517// destination register.
9518// It can optionally update the condition flags based on the result.
9519bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9520                                          const ARMEncoding encoding) {
9521#if 0
9522    // ARM pseudo code...
9523    if ConditionPassed() then
9524        EncodingSpecificOperations();
9525        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9526        if d == 15 then         // Can only occur for ARM encoding
9527            ALUWritePC(result); // setflags is always FALSE here
9528        else
9529            R[d] = result;
9530            if setflags then
9531                APSR.N = result<31>;
9532                APSR.Z = IsZeroBit(result);
9533                APSR.C = carry;
9534                APSR.V = overflow;
9535#endif
9536
9537  bool success = false;
9538
9539  uint32_t Rd; // the destination register
9540  uint32_t Rn; // the first operand
9541  bool setflags;
9542  uint32_t
9543      imm32; // the immediate value to be added to the value obtained from Rn
9544  switch (encoding) {
9545  case eEncodingT1:
9546    Rd = Bits32(opcode, 11, 8);
9547    Rn = Bits32(opcode, 19, 16);
9548    setflags = BitIsSet(opcode, 20);
9549    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9550    if (BadReg(Rd) || BadReg(Rn))
9551      return false;
9552    break;
9553  case eEncodingA1:
9554    Rd = Bits32(opcode, 15, 12);
9555    Rn = Bits32(opcode, 19, 16);
9556    setflags = BitIsSet(opcode, 20);
9557    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
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 the operand register Rn.
9568  uint32_t reg_val = ReadCoreReg(Rn, &success);
9569  if (!success)
9570    return false;
9571
9572  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9573
9574  EmulateInstruction::Context context;
9575  context.type = EmulateInstruction::eContextImmediate;
9576  context.SetNoArgs();
9577
9578  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9579                                 res.carry_out, res.overflow))
9580    return false;
9581
9582  return true;
9583}
9584
9585// Subtract with Carry (register) subtracts an optionally-shifted register value
9586// and the value of
9587// NOT (Carry flag) from a register value, and writes the result to the
9588// destination register.
9589// It can optionally update the condition flags based on the result.
9590bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9591                                          const ARMEncoding encoding) {
9592#if 0
9593    // ARM pseudo code...
9594    if ConditionPassed() then
9595        EncodingSpecificOperations();
9596        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9597        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9598        if d == 15 then         // Can only occur for ARM encoding
9599            ALUWritePC(result); // setflags is always FALSE here
9600        else
9601            R[d] = result;
9602            if setflags then
9603                APSR.N = result<31>;
9604                APSR.Z = IsZeroBit(result);
9605                APSR.C = carry;
9606                APSR.V = overflow;
9607#endif
9608
9609  bool success = false;
9610
9611  uint32_t Rd; // the destination register
9612  uint32_t Rn; // the first operand
9613  uint32_t Rm; // the second operand
9614  bool setflags;
9615  ARM_ShifterType shift_t;
9616  uint32_t shift_n; // the shift applied to the value read from Rm
9617  switch (encoding) {
9618  case eEncodingT1:
9619    Rd = Rn = Bits32(opcode, 2, 0);
9620    Rm = Bits32(opcode, 5, 3);
9621    setflags = !InITBlock();
9622    shift_t = SRType_LSL;
9623    shift_n = 0;
9624    break;
9625  case eEncodingT2:
9626    Rd = Bits32(opcode, 11, 8);
9627    Rn = Bits32(opcode, 19, 16);
9628    Rm = Bits32(opcode, 3, 0);
9629    setflags = BitIsSet(opcode, 20);
9630    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9631    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9632      return false;
9633    break;
9634  case eEncodingA1:
9635    Rd = Bits32(opcode, 15, 12);
9636    Rn = Bits32(opcode, 19, 16);
9637    Rm = Bits32(opcode, 3, 0);
9638    setflags = BitIsSet(opcode, 20);
9639    shift_n = DecodeImmShiftARM(opcode, shift_t);
9640
9641    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9642    // instructions;
9643    if (Rd == 15 && setflags)
9644      return EmulateSUBSPcLrEtc(opcode, encoding);
9645    break;
9646  default:
9647    return false;
9648  }
9649  // Read the register value from register Rn.
9650  uint32_t val1 = ReadCoreReg(Rn, &success);
9651  if (!success)
9652    return false;
9653
9654  // Read the register value from register Rm.
9655  uint32_t val2 = ReadCoreReg(Rm, &success);
9656  if (!success)
9657    return false;
9658
9659  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9660  if (!success)
9661    return false;
9662  AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9663
9664  EmulateInstruction::Context context;
9665  context.type = EmulateInstruction::eContextImmediate;
9666  context.SetNoArgs();
9667  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9668                                 res.carry_out, res.overflow))
9669    return false;
9670
9671  return true;
9672}
9673
9674// This instruction subtracts an immediate value from a register value, and
9675// writes the result
9676// to the destination register.  It can optionally update the condition flags
9677// based on the result.
9678bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9679                                               const ARMEncoding encoding) {
9680#if 0
9681    // ARM pseudo code...
9682    if ConditionPassed() then
9683        EncodingSpecificOperations();
9684        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9685        R[d] = result;
9686        if setflags then
9687            APSR.N = result<31>;
9688            APSR.Z = IsZeroBit(result);
9689            APSR.C = carry;
9690            APSR.V = overflow;
9691#endif
9692
9693  bool success = false;
9694
9695  uint32_t Rd; // the destination register
9696  uint32_t Rn; // the first operand
9697  bool setflags;
9698  uint32_t imm32; // the immediate value to be subtracted from the value
9699                  // obtained from Rn
9700  switch (encoding) {
9701  case eEncodingT1:
9702    Rd = Bits32(opcode, 2, 0);
9703    Rn = Bits32(opcode, 5, 3);
9704    setflags = !InITBlock();
9705    imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9706    break;
9707  case eEncodingT2:
9708    Rd = Rn = Bits32(opcode, 10, 8);
9709    setflags = !InITBlock();
9710    imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9711    break;
9712  case eEncodingT3:
9713    Rd = Bits32(opcode, 11, 8);
9714    Rn = Bits32(opcode, 19, 16);
9715    setflags = BitIsSet(opcode, 20);
9716    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9717
9718    // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9719    if (Rd == 15 && setflags)
9720      return EmulateCMPImm(opcode, eEncodingT2);
9721
9722    // if Rn == '1101' then SEE SUB (SP minus immediate);
9723    if (Rn == 13)
9724      return EmulateSUBSPImm(opcode, eEncodingT2);
9725
9726    // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9727    if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9728      return false;
9729    break;
9730  case eEncodingT4:
9731    Rd = Bits32(opcode, 11, 8);
9732    Rn = Bits32(opcode, 19, 16);
9733    setflags = BitIsSet(opcode, 20);
9734    imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9735
9736    // if Rn == '1111' then SEE ADR;
9737    if (Rn == 15)
9738      return EmulateADR(opcode, eEncodingT2);
9739
9740    // if Rn == '1101' then SEE SUB (SP minus immediate);
9741    if (Rn == 13)
9742      return EmulateSUBSPImm(opcode, eEncodingT3);
9743
9744    if (BadReg(Rd))
9745      return false;
9746    break;
9747  default:
9748    return false;
9749  }
9750  // Read the register value from the operand register Rn.
9751  uint32_t reg_val = ReadCoreReg(Rn, &success);
9752  if (!success)
9753    return false;
9754
9755  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9756
9757  EmulateInstruction::Context context;
9758  context.type = EmulateInstruction::eContextImmediate;
9759  context.SetNoArgs();
9760
9761  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9762                                 res.carry_out, res.overflow))
9763    return false;
9764
9765  return true;
9766}
9767
9768// This instruction subtracts an immediate value from a register value, and
9769// writes the result
9770// to the destination register.  It can optionally update the condition flags
9771// based on the result.
9772bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9773                                             const ARMEncoding encoding) {
9774#if 0
9775    // ARM pseudo code...
9776    if ConditionPassed() then
9777        EncodingSpecificOperations();
9778        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9779        if d == 15 then
9780            ALUWritePC(result); // setflags is always FALSE here
9781        else
9782            R[d] = result;
9783            if setflags then
9784                APSR.N = result<31>;
9785                APSR.Z = IsZeroBit(result);
9786                APSR.C = carry;
9787                APSR.V = overflow;
9788#endif
9789
9790  bool success = false;
9791
9792  if (ConditionPassed(opcode)) {
9793    uint32_t Rd; // the destination register
9794    uint32_t Rn; // the first operand
9795    bool setflags;
9796    uint32_t imm32; // the immediate value to be subtracted from the value
9797                    // obtained from Rn
9798    switch (encoding) {
9799    case eEncodingA1:
9800      Rd = Bits32(opcode, 15, 12);
9801      Rn = Bits32(opcode, 19, 16);
9802      setflags = BitIsSet(opcode, 20);
9803      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9804
9805      // if Rn == '1111' && S == '0' then SEE ADR;
9806      if (Rn == 15 && !setflags)
9807        return EmulateADR(opcode, eEncodingA2);
9808
9809      // if Rn == '1101' then SEE SUB (SP minus immediate);
9810      if (Rn == 13)
9811        return EmulateSUBSPImm(opcode, eEncodingA1);
9812
9813      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9814      // instructions;
9815      if (Rd == 15 && setflags)
9816        return EmulateSUBSPcLrEtc(opcode, encoding);
9817      break;
9818    default:
9819      return false;
9820    }
9821    // Read the register value from the operand register Rn.
9822    uint32_t reg_val = ReadCoreReg(Rn, &success);
9823    if (!success)
9824      return false;
9825
9826    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9827
9828    EmulateInstruction::Context context;
9829    if (Rd == 13)
9830      context.type = EmulateInstruction::eContextAdjustStackPointer;
9831    else
9832      context.type = EmulateInstruction::eContextRegisterPlusOffset;
9833
9834    RegisterInfo dwarf_reg;
9835    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9836    int64_t imm32_signed = imm32;
9837    context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9838
9839    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9840                                   res.carry_out, res.overflow))
9841      return false;
9842  }
9843  return true;
9844}
9845
9846// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9847// register value and an
9848// immediate value.  It updates the condition flags based on the result, and
9849// discards the result.
9850bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9851                                          const ARMEncoding encoding) {
9852#if 0
9853    // ARM pseudo code...
9854    if ConditionPassed() then
9855        EncodingSpecificOperations();
9856        result = R[n] EOR imm32;
9857        APSR.N = result<31>;
9858        APSR.Z = IsZeroBit(result);
9859        APSR.C = carry;
9860        // APSR.V unchanged
9861#endif
9862
9863  bool success = false;
9864
9865  if (ConditionPassed(opcode)) {
9866    uint32_t Rn;
9867    uint32_t
9868        imm32; // the immediate value to be ANDed to the value obtained from Rn
9869    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9870    switch (encoding) {
9871    case eEncodingT1:
9872      Rn = Bits32(opcode, 19, 16);
9873      imm32 = ThumbExpandImm_C(
9874          opcode, APSR_C,
9875          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9876      if (BadReg(Rn))
9877        return false;
9878      break;
9879    case eEncodingA1:
9880      Rn = Bits32(opcode, 19, 16);
9881      imm32 =
9882          ARMExpandImm_C(opcode, APSR_C,
9883                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9884      break;
9885    default:
9886      return false;
9887    }
9888
9889    // Read the first operand.
9890    uint32_t val1 = ReadCoreReg(Rn, &success);
9891    if (!success)
9892      return false;
9893
9894    uint32_t result = val1 ^ imm32;
9895
9896    EmulateInstruction::Context context;
9897    context.type = EmulateInstruction::eContextImmediate;
9898    context.SetNoArgs();
9899
9900    if (!WriteFlags(context, result, carry))
9901      return false;
9902  }
9903  return true;
9904}
9905
9906// Test Equivalence (register) performs a bitwise exclusive OR operation on a
9907// register value and an
9908// optionally-shifted register value.  It updates the condition flags based on
9909// the result, and discards
9910// the result.
9911bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9912                                          const ARMEncoding encoding) {
9913#if 0
9914    // ARM pseudo code...
9915    if ConditionPassed() then
9916        EncodingSpecificOperations();
9917        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9918        result = R[n] EOR shifted;
9919        APSR.N = result<31>;
9920        APSR.Z = IsZeroBit(result);
9921        APSR.C = carry;
9922        // APSR.V unchanged
9923#endif
9924
9925  bool success = false;
9926
9927  if (ConditionPassed(opcode)) {
9928    uint32_t Rn, Rm;
9929    ARM_ShifterType shift_t;
9930    uint32_t shift_n; // the shift applied to the value read from Rm
9931    uint32_t carry;
9932    switch (encoding) {
9933    case eEncodingT1:
9934      Rn = Bits32(opcode, 19, 16);
9935      Rm = Bits32(opcode, 3, 0);
9936      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9937      if (BadReg(Rn) || BadReg(Rm))
9938        return false;
9939      break;
9940    case eEncodingA1:
9941      Rn = Bits32(opcode, 19, 16);
9942      Rm = Bits32(opcode, 3, 0);
9943      shift_n = DecodeImmShiftARM(opcode, shift_t);
9944      break;
9945    default:
9946      return false;
9947    }
9948
9949    // Read the first operand.
9950    uint32_t val1 = ReadCoreReg(Rn, &success);
9951    if (!success)
9952      return false;
9953
9954    // Read the second operand.
9955    uint32_t val2 = ReadCoreReg(Rm, &success);
9956    if (!success)
9957      return false;
9958
9959    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9960    if (!success)
9961      return false;
9962    uint32_t result = val1 ^ shifted;
9963
9964    EmulateInstruction::Context context;
9965    context.type = EmulateInstruction::eContextImmediate;
9966    context.SetNoArgs();
9967
9968    if (!WriteFlags(context, result, carry))
9969      return false;
9970  }
9971  return true;
9972}
9973
9974// Test (immediate) performs a bitwise AND operation on a register value and an
9975// immediate value.
9976// It updates the condition flags based on the result, and discards the result.
9977bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9978                                          const ARMEncoding encoding) {
9979#if 0
9980    // ARM pseudo code...
9981    if ConditionPassed() then
9982        EncodingSpecificOperations();
9983        result = R[n] AND imm32;
9984        APSR.N = result<31>;
9985        APSR.Z = IsZeroBit(result);
9986        APSR.C = carry;
9987        // APSR.V unchanged
9988#endif
9989
9990  bool success = false;
9991
9992  if (ConditionPassed(opcode)) {
9993    uint32_t Rn;
9994    uint32_t
9995        imm32; // the immediate value to be ANDed to the value obtained from Rn
9996    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9997    switch (encoding) {
9998    case eEncodingT1:
9999      Rn = Bits32(opcode, 19, 16);
10000      imm32 = ThumbExpandImm_C(
10001          opcode, APSR_C,
10002          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
10003      if (BadReg(Rn))
10004        return false;
10005      break;
10006    case eEncodingA1:
10007      Rn = Bits32(opcode, 19, 16);
10008      imm32 =
10009          ARMExpandImm_C(opcode, APSR_C,
10010                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
10011      break;
10012    default:
10013      return false;
10014    }
10015
10016    // Read the first operand.
10017    uint32_t val1 = ReadCoreReg(Rn, &success);
10018    if (!success)
10019      return false;
10020
10021    uint32_t result = val1 & imm32;
10022
10023    EmulateInstruction::Context context;
10024    context.type = EmulateInstruction::eContextImmediate;
10025    context.SetNoArgs();
10026
10027    if (!WriteFlags(context, result, carry))
10028      return false;
10029  }
10030  return true;
10031}
10032
10033// Test (register) performs a bitwise AND operation on a register value and an
10034// optionally-shifted register value.
10035// It updates the condition flags based on the result, and discards the result.
10036bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
10037                                          const ARMEncoding encoding) {
10038#if 0
10039    // ARM pseudo code...
10040    if ConditionPassed() then
10041        EncodingSpecificOperations();
10042        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
10043        result = R[n] AND shifted;
10044        APSR.N = result<31>;
10045        APSR.Z = IsZeroBit(result);
10046        APSR.C = carry;
10047        // APSR.V unchanged
10048#endif
10049
10050  bool success = false;
10051
10052  if (ConditionPassed(opcode)) {
10053    uint32_t Rn, Rm;
10054    ARM_ShifterType shift_t;
10055    uint32_t shift_n; // the shift applied to the value read from Rm
10056    uint32_t carry;
10057    switch (encoding) {
10058    case eEncodingT1:
10059      Rn = Bits32(opcode, 2, 0);
10060      Rm = Bits32(opcode, 5, 3);
10061      shift_t = SRType_LSL;
10062      shift_n = 0;
10063      break;
10064    case eEncodingT2:
10065      Rn = Bits32(opcode, 19, 16);
10066      Rm = Bits32(opcode, 3, 0);
10067      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10068      if (BadReg(Rn) || BadReg(Rm))
10069        return false;
10070      break;
10071    case eEncodingA1:
10072      Rn = Bits32(opcode, 19, 16);
10073      Rm = Bits32(opcode, 3, 0);
10074      shift_n = DecodeImmShiftARM(opcode, shift_t);
10075      break;
10076    default:
10077      return false;
10078    }
10079
10080    // Read the first operand.
10081    uint32_t val1 = ReadCoreReg(Rn, &success);
10082    if (!success)
10083      return false;
10084
10085    // Read the second operand.
10086    uint32_t val2 = ReadCoreReg(Rm, &success);
10087    if (!success)
10088      return false;
10089
10090    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
10091    if (!success)
10092      return false;
10093    uint32_t result = val1 & shifted;
10094
10095    EmulateInstruction::Context context;
10096    context.type = EmulateInstruction::eContextImmediate;
10097    context.SetNoArgs();
10098
10099    if (!WriteFlags(context, result, carry))
10100      return false;
10101  }
10102  return true;
10103}
10104
10105// A8.6.216 SUB (SP minus register)
10106bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10107                                            const ARMEncoding encoding) {
10108#if 0
10109    if ConditionPassed() then
10110        EncodingSpecificOperations();
10111        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10112        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10113        if d == 15 then // Can only occur for ARM encoding
10114            ALUWritePC(result); // setflags is always FALSE here
10115        else
10116            R[d] = result;
10117            if setflags then
10118                APSR.N = result<31>;
10119                APSR.Z = IsZeroBit(result);
10120                APSR.C = carry;
10121                APSR.V = overflow;
10122#endif
10123
10124  bool success = false;
10125
10126  if (ConditionPassed(opcode)) {
10127    uint32_t d;
10128    uint32_t m;
10129    bool setflags;
10130    ARM_ShifterType shift_t;
10131    uint32_t shift_n;
10132
10133    switch (encoding) {
10134    case eEncodingT1:
10135      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10136      d = Bits32(opcode, 11, 8);
10137      m = Bits32(opcode, 3, 0);
10138      setflags = BitIsSet(opcode, 20);
10139
10140      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10141      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10142
10143      // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10144      // UNPREDICTABLE;
10145      if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10146        return false;
10147
10148      // if d == 15 || BadReg(m) then UNPREDICTABLE;
10149      if ((d == 15) || BadReg(m))
10150        return false;
10151      break;
10152
10153    case eEncodingA1:
10154      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10155      d = Bits32(opcode, 15, 12);
10156      m = Bits32(opcode, 3, 0);
10157      setflags = BitIsSet(opcode, 20);
10158
10159      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10160      // instructions;
10161      if (d == 15 && setflags)
10162        EmulateSUBSPcLrEtc(opcode, encoding);
10163
10164      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10165      shift_n = DecodeImmShiftARM(opcode, shift_t);
10166      break;
10167
10168    default:
10169      return false;
10170    }
10171
10172    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10173    uint32_t Rm = ReadCoreReg(m, &success);
10174    if (!success)
10175      return false;
10176
10177    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10178    if (!success)
10179      return false;
10180
10181    // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10182    uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10183    if (!success)
10184      return false;
10185
10186    AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10187
10188    EmulateInstruction::Context context;
10189    context.type = eContextArithmetic;
10190    RegisterInfo sp_reg;
10191    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10192    RegisterInfo dwarf_reg;
10193    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10194    context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10195
10196    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10197                                   res.carry_out, res.overflow))
10198      return false;
10199  }
10200  return true;
10201}
10202
10203// A8.6.7 ADD (register-shifted register)
10204bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10205                                               const ARMEncoding encoding) {
10206#if 0
10207    if ConditionPassed() then
10208        EncodingSpecificOperations();
10209        shift_n = UInt(R[s]<7:0>);
10210        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10211        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10212        R[d] = result;
10213        if setflags then
10214            APSR.N = result<31>;
10215            APSR.Z = IsZeroBit(result);
10216            APSR.C = carry;
10217            APSR.V = overflow;
10218#endif
10219
10220  bool success = false;
10221
10222  if (ConditionPassed(opcode)) {
10223    uint32_t d;
10224    uint32_t n;
10225    uint32_t m;
10226    uint32_t s;
10227    bool setflags;
10228    ARM_ShifterType shift_t;
10229
10230    switch (encoding) {
10231    case eEncodingA1:
10232      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10233      d = Bits32(opcode, 15, 12);
10234      n = Bits32(opcode, 19, 16);
10235      m = Bits32(opcode, 3, 0);
10236      s = Bits32(opcode, 11, 8);
10237
10238      // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10239      setflags = BitIsSet(opcode, 20);
10240      shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10241
10242      // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10243      if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
10244        return false;
10245      break;
10246
10247    default:
10248      return false;
10249    }
10250
10251    // shift_n = UInt(R[s]<7:0>);
10252    uint32_t Rs = ReadCoreReg(s, &success);
10253    if (!success)
10254      return false;
10255
10256    uint32_t shift_n = Bits32(Rs, 7, 0);
10257
10258    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10259    uint32_t Rm = ReadCoreReg(m, &success);
10260    if (!success)
10261      return false;
10262
10263    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10264    if (!success)
10265      return false;
10266
10267    // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10268    uint32_t Rn = ReadCoreReg(n, &success);
10269    if (!success)
10270      return false;
10271
10272    AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10273
10274    // R[d] = result;
10275    EmulateInstruction::Context context;
10276    context.type = eContextArithmetic;
10277    RegisterInfo reg_n;
10278    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10279    RegisterInfo reg_m;
10280    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10281
10282    context.SetRegisterRegisterOperands(reg_n, reg_m);
10283
10284    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10285                               res.result))
10286      return false;
10287
10288    // if setflags then
10289    // APSR.N = result<31>;
10290    // APSR.Z = IsZeroBit(result);
10291    // APSR.C = carry;
10292    // APSR.V = overflow;
10293    if (setflags)
10294      return WriteFlags(context, res.result, res.carry_out, res.overflow);
10295  }
10296  return true;
10297}
10298
10299// A8.6.213 SUB (register)
10300bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10301                                          const ARMEncoding encoding) {
10302#if 0
10303    if ConditionPassed() then
10304        EncodingSpecificOperations();
10305        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10306        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10307        if d == 15 then // Can only occur for ARM encoding
10308            ALUWritePC(result); // setflags is always FALSE here
10309        else
10310            R[d] = result;
10311            if setflags then
10312                APSR.N = result<31>;
10313                APSR.Z = IsZeroBit(result);
10314                APSR.C = carry;
10315                APSR.V = overflow;
10316#endif
10317
10318  bool success = false;
10319
10320  if (ConditionPassed(opcode)) {
10321    uint32_t d;
10322    uint32_t n;
10323    uint32_t m;
10324    bool setflags;
10325    ARM_ShifterType shift_t;
10326    uint32_t shift_n;
10327
10328    switch (encoding) {
10329    case eEncodingT1:
10330      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10331      d = Bits32(opcode, 2, 0);
10332      n = Bits32(opcode, 5, 3);
10333      m = Bits32(opcode, 8, 6);
10334      setflags = !InITBlock();
10335
10336      // (shift_t, shift_n) = (SRType_LSL, 0);
10337      shift_t = SRType_LSL;
10338      shift_n = 0;
10339
10340      break;
10341
10342    case eEncodingT2:
10343      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10344      d = Bits32(opcode, 11, 8);
10345      n = Bits32(opcode, 19, 16);
10346      m = Bits32(opcode, 3, 0);
10347      setflags = BitIsSet(opcode, 20);
10348
10349      // if Rd == "1111" && S == "1" then SEE CMP (register);
10350      if (d == 15 && setflags == 1)
10351        return EmulateCMPImm(opcode, eEncodingT3);
10352
10353      // if Rn == "1101" then SEE SUB (SP minus register);
10354      if (n == 13)
10355        return EmulateSUBSPReg(opcode, eEncodingT1);
10356
10357      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10358      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10359
10360      // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10361      // UNPREDICTABLE;
10362      if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10363          BadReg(m))
10364        return false;
10365
10366      break;
10367
10368    case eEncodingA1:
10369      // if Rn == '1101' then SEE SUB (SP minus register);
10370      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10371      d = Bits32(opcode, 15, 12);
10372      n = Bits32(opcode, 19, 16);
10373      m = Bits32(opcode, 3, 0);
10374      setflags = BitIsSet(opcode, 20);
10375
10376      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10377      // instructions;
10378      if ((d == 15) && setflags)
10379        EmulateSUBSPcLrEtc(opcode, encoding);
10380
10381      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10382      shift_n = DecodeImmShiftARM(opcode, shift_t);
10383
10384      break;
10385
10386    default:
10387      return false;
10388    }
10389
10390    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10391    uint32_t Rm = ReadCoreReg(m, &success);
10392    if (!success)
10393      return false;
10394
10395    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10396    if (!success)
10397      return false;
10398
10399    // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10400    uint32_t Rn = ReadCoreReg(n, &success);
10401    if (!success)
10402      return false;
10403
10404    AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10405
10406    // if d == 15 then // Can only occur for ARM encoding
10407    // ALUWritePC(result); // setflags is always FALSE here
10408    // else
10409    // R[d] = result;
10410    // if setflags then
10411    // APSR.N = result<31>;
10412    // APSR.Z = IsZeroBit(result);
10413    // APSR.C = carry;
10414    // APSR.V = overflow;
10415
10416    EmulateInstruction::Context context;
10417    context.type = eContextArithmetic;
10418    RegisterInfo reg_n;
10419    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10420    RegisterInfo reg_m;
10421    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10422    context.SetRegisterRegisterOperands(reg_n, reg_m);
10423
10424    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10425                                   res.carry_out, res.overflow))
10426      return false;
10427  }
10428  return true;
10429}
10430
10431// A8.6.202 STREX
10432// Store Register Exclusive calculates an address from a base register value and
10433// an immediate offset, and stores a
10434// word from a register to memory if the executing processor has exclusive
10435// access to the memory addressed.
10436bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10437                                         const ARMEncoding encoding) {
10438#if 0
10439    if ConditionPassed() then
10440        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10441        address = R[n] + imm32;
10442        if ExclusiveMonitorsPass(address,4) then
10443            MemA[address,4] = R[t];
10444            R[d] = 0;
10445        else
10446            R[d] = 1;
10447#endif
10448
10449  bool success = false;
10450
10451  if (ConditionPassed(opcode)) {
10452    uint32_t d;
10453    uint32_t t;
10454    uint32_t n;
10455    uint32_t imm32;
10456    const uint32_t addr_byte_size = GetAddressByteSize();
10457
10458    switch (encoding) {
10459    case eEncodingT1:
10460      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00',
10461      // 32);
10462      d = Bits32(opcode, 11, 8);
10463      t = Bits32(opcode, 15, 12);
10464      n = Bits32(opcode, 19, 16);
10465      imm32 = Bits32(opcode, 7, 0) << 2;
10466
10467      // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10468      if (BadReg(d) || BadReg(t) || (n == 15))
10469        return false;
10470
10471      // if d == n || d == t then UNPREDICTABLE;
10472      if ((d == n) || (d == t))
10473        return false;
10474
10475      break;
10476
10477    case eEncodingA1:
10478      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10479      // offset
10480      d = Bits32(opcode, 15, 12);
10481      t = Bits32(opcode, 3, 0);
10482      n = Bits32(opcode, 19, 16);
10483      imm32 = 0;
10484
10485      // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10486      if ((d == 15) || (t == 15) || (n == 15))
10487        return false;
10488
10489      // if d == n || d == t then UNPREDICTABLE;
10490      if ((d == n) || (d == t))
10491        return false;
10492
10493      break;
10494
10495    default:
10496      return false;
10497    }
10498
10499    // address = R[n] + imm32;
10500    uint32_t Rn = ReadCoreReg(n, &success);
10501    if (!success)
10502      return false;
10503
10504    addr_t address = Rn + imm32;
10505
10506    RegisterInfo base_reg;
10507    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10508    RegisterInfo data_reg;
10509    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10510    EmulateInstruction::Context context;
10511    context.type = eContextRegisterStore;
10512    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10513
10514    // if ExclusiveMonitorsPass(address,4) then
10515    // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the
10516    // sake of emulation, we will say this
10517    //                                                         always return
10518    //                                                         true.
10519    if (true) {
10520      // MemA[address,4] = R[t];
10521      uint32_t Rt =
10522          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10523      if (!success)
10524        return false;
10525
10526      if (!MemAWrite(context, address, Rt, addr_byte_size))
10527        return false;
10528
10529      // R[d] = 0;
10530      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10531        return false;
10532    }
10533#if 0  // unreachable because if true
10534        else
10535        {
10536            // R[d] = 1;
10537            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10538                return false;
10539        }
10540#endif // unreachable because if true
10541  }
10542  return true;
10543}
10544
10545// A8.6.197 STRB (immediate, ARM)
10546bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10547                                              const ARMEncoding encoding) {
10548#if 0
10549    if ConditionPassed() then
10550        EncodingSpecificOperations();
10551        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10552        address = if index then offset_addr else R[n];
10553        MemU[address,1] = R[t]<7:0>;
10554        if wback then R[n] = offset_addr;
10555#endif
10556
10557  bool success = false;
10558
10559  if (ConditionPassed(opcode)) {
10560    uint32_t t;
10561    uint32_t n;
10562    uint32_t imm32;
10563    bool index;
10564    bool add;
10565    bool wback;
10566
10567    switch (encoding) {
10568    case eEncodingA1:
10569      // if P == '0' && W == '1' then SEE STRBT;
10570      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10571      t = Bits32(opcode, 15, 12);
10572      n = Bits32(opcode, 19, 16);
10573      imm32 = Bits32(opcode, 11, 0);
10574
10575      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10576      index = BitIsSet(opcode, 24);
10577      add = BitIsSet(opcode, 23);
10578      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10579
10580      // if t == 15 then UNPREDICTABLE;
10581      if (t == 15)
10582        return false;
10583
10584      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10585      if (wback && ((n == 15) || (n == t)))
10586        return false;
10587
10588      break;
10589
10590    default:
10591      return false;
10592    }
10593
10594    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10595    uint32_t Rn = ReadCoreReg(n, &success);
10596    if (!success)
10597      return false;
10598
10599    addr_t offset_addr;
10600    if (add)
10601      offset_addr = Rn + imm32;
10602    else
10603      offset_addr = Rn - imm32;
10604
10605    // address = if index then offset_addr else R[n];
10606    addr_t address;
10607    if (index)
10608      address = offset_addr;
10609    else
10610      address = Rn;
10611
10612    // MemU[address,1] = R[t]<7:0>;
10613    uint32_t Rt = ReadCoreReg(t, &success);
10614    if (!success)
10615      return false;
10616
10617    RegisterInfo base_reg;
10618    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10619    RegisterInfo data_reg;
10620    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10621    EmulateInstruction::Context context;
10622    context.type = eContextRegisterStore;
10623    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10624
10625    if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10626      return false;
10627
10628    // if wback then R[n] = offset_addr;
10629    if (wback) {
10630      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10631                                 offset_addr))
10632        return false;
10633    }
10634  }
10635  return true;
10636}
10637
10638// A8.6.194 STR (immediate, ARM)
10639bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10640                                             const ARMEncoding encoding) {
10641#if 0
10642    if ConditionPassed() then
10643        EncodingSpecificOperations();
10644        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10645        address = if index then offset_addr else R[n];
10646        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10647        if wback then R[n] = offset_addr;
10648#endif
10649
10650  bool success = false;
10651
10652  if (ConditionPassed(opcode)) {
10653    uint32_t t;
10654    uint32_t n;
10655    uint32_t imm32;
10656    bool index;
10657    bool add;
10658    bool wback;
10659
10660    const uint32_t addr_byte_size = GetAddressByteSize();
10661
10662    switch (encoding) {
10663    case eEncodingA1:
10664      // if P == '0' && W == '1' then SEE STRT;
10665      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10666      // '000000000100' then SEE PUSH;
10667      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10668      t = Bits32(opcode, 15, 12);
10669      n = Bits32(opcode, 19, 16);
10670      imm32 = Bits32(opcode, 11, 0);
10671
10672      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10673      index = BitIsSet(opcode, 24);
10674      add = BitIsSet(opcode, 23);
10675      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10676
10677      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10678      if (wback && ((n == 15) || (n == t)))
10679        return false;
10680
10681      break;
10682
10683    default:
10684      return false;
10685    }
10686
10687    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10688    uint32_t Rn = ReadCoreReg(n, &success);
10689    if (!success)
10690      return false;
10691
10692    addr_t offset_addr;
10693    if (add)
10694      offset_addr = Rn + imm32;
10695    else
10696      offset_addr = Rn - imm32;
10697
10698    // address = if index then offset_addr else R[n];
10699    addr_t address;
10700    if (index)
10701      address = offset_addr;
10702    else
10703      address = Rn;
10704
10705    RegisterInfo base_reg;
10706    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10707    RegisterInfo data_reg;
10708    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10709    EmulateInstruction::Context context;
10710    context.type = eContextRegisterStore;
10711    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10712
10713    // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10714    uint32_t Rt = ReadCoreReg(t, &success);
10715    if (!success)
10716      return false;
10717
10718    if (t == 15) {
10719      uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10720      if (!success)
10721        return false;
10722
10723      if (!MemUWrite(context, address, pc_value, addr_byte_size))
10724        return false;
10725    } else {
10726      if (!MemUWrite(context, address, Rt, addr_byte_size))
10727        return false;
10728    }
10729
10730    // if wback then R[n] = offset_addr;
10731    if (wback) {
10732      context.type = eContextAdjustBaseRegister;
10733      context.SetImmediate(offset_addr);
10734
10735      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10736                                 offset_addr))
10737        return false;
10738    }
10739  }
10740  return true;
10741}
10742
10743// A8.6.66 LDRD (immediate)
10744// Load Register Dual (immediate) calculates an address from a base register
10745// value and an immediate offset, loads two
10746// words from memory, and writes them to two registers.  It can use offset,
10747// post-indexed, or pre-indexed addressing.
10748bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10749                                                 const ARMEncoding encoding) {
10750#if 0
10751    if ConditionPassed() then
10752        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10753        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10754        address = if index then offset_addr else R[n];
10755        R[t] = MemA[address,4];
10756        R[t2] = MemA[address+4,4];
10757        if wback then R[n] = offset_addr;
10758#endif
10759
10760  bool success = false;
10761
10762  if (ConditionPassed(opcode)) {
10763    uint32_t t;
10764    uint32_t t2;
10765    uint32_t n;
10766    uint32_t imm32;
10767    bool index;
10768    bool add;
10769    bool wback;
10770
10771    switch (encoding) {
10772    case eEncodingT1:
10773      // if P == '0' && W == '0' then SEE 'Related encodings';
10774      // if Rn == '1111' then SEE LDRD (literal);
10775      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10776      // ZeroExtend(imm8:'00', 32);
10777      t = Bits32(opcode, 15, 12);
10778      t2 = Bits32(opcode, 11, 8);
10779      n = Bits32(opcode, 19, 16);
10780      imm32 = Bits32(opcode, 7, 0) << 2;
10781
10782      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10783      index = BitIsSet(opcode, 24);
10784      add = BitIsSet(opcode, 23);
10785      wback = BitIsSet(opcode, 21);
10786
10787      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10788      if (wback && ((n == t) || (n == t2)))
10789        return false;
10790
10791      // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10792      if (BadReg(t) || BadReg(t2) || (t == t2))
10793        return false;
10794
10795      break;
10796
10797    case eEncodingA1:
10798      // if Rn == '1111' then SEE LDRD (literal);
10799      // if Rt<0> == '1' then UNPREDICTABLE;
10800      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10801      // 32);
10802      t = Bits32(opcode, 15, 12);
10803      if (BitIsSet(t, 0))
10804        return false;
10805      t2 = t + 1;
10806      n = Bits32(opcode, 19, 16);
10807      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10808
10809      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10810      index = BitIsSet(opcode, 24);
10811      add = BitIsSet(opcode, 23);
10812      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10813
10814      // if P == '0' && W == '1' then UNPREDICTABLE;
10815      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10816        return false;
10817
10818      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10819      if (wback && ((n == t) || (n == t2)))
10820        return false;
10821
10822      // if t2 == 15 then UNPREDICTABLE;
10823      if (t2 == 15)
10824        return false;
10825
10826      break;
10827
10828    default:
10829      return false;
10830    }
10831
10832    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10833    uint32_t Rn = ReadCoreReg(n, &success);
10834    if (!success)
10835      return false;
10836
10837    addr_t offset_addr;
10838    if (add)
10839      offset_addr = Rn + imm32;
10840    else
10841      offset_addr = Rn - imm32;
10842
10843    // address = if index then offset_addr else R[n];
10844    addr_t address;
10845    if (index)
10846      address = offset_addr;
10847    else
10848      address = Rn;
10849
10850    // R[t] = MemA[address,4];
10851    RegisterInfo base_reg;
10852    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10853
10854    EmulateInstruction::Context context;
10855    if (n == 13)
10856      context.type = eContextPopRegisterOffStack;
10857    else
10858      context.type = eContextRegisterLoad;
10859    context.SetAddress(address);
10860
10861    const uint32_t addr_byte_size = GetAddressByteSize();
10862    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10863    if (!success)
10864      return false;
10865
10866    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10867      return false;
10868
10869    // R[t2] = MemA[address+4,4];
10870    context.SetAddress(address + 4);
10871    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10872    if (!success)
10873      return false;
10874
10875    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10876                               data))
10877      return false;
10878
10879    // if wback then R[n] = offset_addr;
10880    if (wback) {
10881      context.type = eContextAdjustBaseRegister;
10882      context.SetAddress(offset_addr);
10883
10884      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10885                                 offset_addr))
10886        return false;
10887    }
10888  }
10889  return true;
10890}
10891
10892// A8.6.68 LDRD (register)
10893// Load Register Dual (register) calculates an address from a base register
10894// value and a register offset, loads two
10895// words from memory, and writes them to two registers.  It can use offset,
10896// post-indexed or pre-indexed addressing.
10897bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10898                                                const ARMEncoding encoding) {
10899#if 0
10900    if ConditionPassed() then
10901        EncodingSpecificOperations();
10902        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10903        address = if index then offset_addr else R[n];
10904        R[t] = MemA[address,4];
10905        R[t2] = MemA[address+4,4];
10906        if wback then R[n] = offset_addr;
10907#endif
10908
10909  bool success = false;
10910
10911  if (ConditionPassed(opcode)) {
10912    uint32_t t;
10913    uint32_t t2;
10914    uint32_t n;
10915    uint32_t m;
10916    bool index;
10917    bool add;
10918    bool wback;
10919
10920    switch (encoding) {
10921    case eEncodingA1:
10922      // if Rt<0> == '1' then UNPREDICTABLE;
10923      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10924      t = Bits32(opcode, 15, 12);
10925      if (BitIsSet(t, 0))
10926        return false;
10927      t2 = t + 1;
10928      n = Bits32(opcode, 19, 16);
10929      m = Bits32(opcode, 3, 0);
10930
10931      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10932      index = BitIsSet(opcode, 24);
10933      add = BitIsSet(opcode, 23);
10934      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10935
10936      // if P == '0' && W == '1' then UNPREDICTABLE;
10937      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10938        return false;
10939
10940      // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10941      if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10942        return false;
10943
10944      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10945      if (wback && ((n == 15) || (n == t) || (n == t2)))
10946        return false;
10947
10948      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10949      if ((ArchVersion() < 6) && wback && (m == n))
10950        return false;
10951      break;
10952
10953    default:
10954      return false;
10955    }
10956
10957    uint32_t Rn = ReadCoreReg(n, &success);
10958    if (!success)
10959      return false;
10960    RegisterInfo base_reg;
10961    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10962
10963    uint32_t Rm = ReadCoreReg(m, &success);
10964    if (!success)
10965      return false;
10966    RegisterInfo offset_reg;
10967    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10968
10969    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10970    addr_t offset_addr;
10971    if (add)
10972      offset_addr = Rn + Rm;
10973    else
10974      offset_addr = Rn - Rm;
10975
10976    // address = if index then offset_addr else R[n];
10977    addr_t address;
10978    if (index)
10979      address = offset_addr;
10980    else
10981      address = Rn;
10982
10983    EmulateInstruction::Context context;
10984    if (n == 13)
10985      context.type = eContextPopRegisterOffStack;
10986    else
10987      context.type = eContextRegisterLoad;
10988    context.SetAddress(address);
10989
10990    // R[t] = MemA[address,4];
10991    const uint32_t addr_byte_size = GetAddressByteSize();
10992    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10993    if (!success)
10994      return false;
10995
10996    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10997      return false;
10998
10999    // R[t2] = MemA[address+4,4];
11000
11001    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
11002    if (!success)
11003      return false;
11004
11005    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
11006                               data))
11007      return false;
11008
11009    // if wback then R[n] = offset_addr;
11010    if (wback) {
11011      context.type = eContextAdjustBaseRegister;
11012      context.SetAddress(offset_addr);
11013
11014      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11015                                 offset_addr))
11016        return false;
11017    }
11018  }
11019  return true;
11020}
11021
11022// A8.6.200 STRD (immediate)
11023// Store Register Dual (immediate) calculates an address from a base register
11024// value and an immediate offset, and
11025// stores two words from two registers to memory.  It can use offset,
11026// post-indexed, or pre-indexed addressing.
11027bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
11028                                           const ARMEncoding encoding) {
11029#if 0
11030    if ConditionPassed() then
11031        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
11032        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11033        address = if index then offset_addr else R[n];
11034        MemA[address,4] = R[t];
11035        MemA[address+4,4] = R[t2];
11036        if wback then R[n] = offset_addr;
11037#endif
11038
11039  bool success = false;
11040
11041  if (ConditionPassed(opcode)) {
11042    uint32_t t;
11043    uint32_t t2;
11044    uint32_t n;
11045    uint32_t imm32;
11046    bool index;
11047    bool add;
11048    bool wback;
11049
11050    switch (encoding) {
11051    case eEncodingT1:
11052      // if P == '0' && W == '0' then SEE 'Related encodings';
11053      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
11054      // ZeroExtend(imm8:'00', 32);
11055      t = Bits32(opcode, 15, 12);
11056      t2 = Bits32(opcode, 11, 8);
11057      n = Bits32(opcode, 19, 16);
11058      imm32 = Bits32(opcode, 7, 0) << 2;
11059
11060      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
11061      index = BitIsSet(opcode, 24);
11062      add = BitIsSet(opcode, 23);
11063      wback = BitIsSet(opcode, 21);
11064
11065      // if wback && (n == t || n == t2) then UNPREDICTABLE;
11066      if (wback && ((n == t) || (n == t2)))
11067        return false;
11068
11069      // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
11070      if ((n == 15) || BadReg(t) || BadReg(t2))
11071        return false;
11072
11073      break;
11074
11075    case eEncodingA1:
11076      // if Rt<0> == '1' then UNPREDICTABLE;
11077      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
11078      // 32);
11079      t = Bits32(opcode, 15, 12);
11080      if (BitIsSet(t, 0))
11081        return false;
11082
11083      t2 = t + 1;
11084      n = Bits32(opcode, 19, 16);
11085      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
11086
11087      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11088      index = BitIsSet(opcode, 24);
11089      add = BitIsSet(opcode, 23);
11090      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11091
11092      // if P == '0' && W == '1' then UNPREDICTABLE;
11093      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11094        return false;
11095
11096      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11097      if (wback && ((n == 15) || (n == t) || (n == t2)))
11098        return false;
11099
11100      // if t2 == 15 then UNPREDICTABLE;
11101      if (t2 == 15)
11102        return false;
11103
11104      break;
11105
11106    default:
11107      return false;
11108    }
11109
11110    RegisterInfo base_reg;
11111    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11112
11113    uint32_t Rn = ReadCoreReg(n, &success);
11114    if (!success)
11115      return false;
11116
11117    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11118    addr_t offset_addr;
11119    if (add)
11120      offset_addr = Rn + imm32;
11121    else
11122      offset_addr = Rn - imm32;
11123
11124    // address = if index then offset_addr else R[n];
11125    addr_t address;
11126    if (index)
11127      address = offset_addr;
11128    else
11129      address = Rn;
11130
11131    // MemA[address,4] = R[t];
11132    RegisterInfo data_reg;
11133    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11134
11135    uint32_t data = ReadCoreReg(t, &success);
11136    if (!success)
11137      return false;
11138
11139    EmulateInstruction::Context context;
11140    if (n == 13)
11141      context.type = eContextPushRegisterOnStack;
11142    else
11143      context.type = eContextRegisterStore;
11144    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11145
11146    const uint32_t addr_byte_size = GetAddressByteSize();
11147
11148    if (!MemAWrite(context, address, data, addr_byte_size))
11149      return false;
11150
11151    // MemA[address+4,4] = R[t2];
11152    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11153    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11154                                            (address + 4) - Rn);
11155
11156    data = ReadCoreReg(t2, &success);
11157    if (!success)
11158      return false;
11159
11160    if (!MemAWrite(context, address + 4, data, addr_byte_size))
11161      return false;
11162
11163    // if wback then R[n] = offset_addr;
11164    if (wback) {
11165      if (n == 13)
11166        context.type = eContextAdjustStackPointer;
11167      else
11168        context.type = eContextAdjustBaseRegister;
11169      context.SetAddress(offset_addr);
11170
11171      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11172                                 offset_addr))
11173        return false;
11174    }
11175  }
11176  return true;
11177}
11178
11179// A8.6.201 STRD (register)
11180bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11181                                           const ARMEncoding encoding) {
11182#if 0
11183    if ConditionPassed() then
11184        EncodingSpecificOperations();
11185        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11186        address = if index then offset_addr else R[n];
11187        MemA[address,4] = R[t];
11188        MemA[address+4,4] = R[t2];
11189        if wback then R[n] = offset_addr;
11190#endif
11191
11192  bool success = false;
11193
11194  if (ConditionPassed(opcode)) {
11195    uint32_t t;
11196    uint32_t t2;
11197    uint32_t n;
11198    uint32_t m;
11199    bool index;
11200    bool add;
11201    bool wback;
11202
11203    switch (encoding) {
11204    case eEncodingA1:
11205      // if Rt<0> == '1' then UNPREDICTABLE;
11206      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11207      t = Bits32(opcode, 15, 12);
11208      if (BitIsSet(t, 0))
11209        return false;
11210
11211      t2 = t + 1;
11212      n = Bits32(opcode, 19, 16);
11213      m = Bits32(opcode, 3, 0);
11214
11215      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11216      index = BitIsSet(opcode, 24);
11217      add = BitIsSet(opcode, 23);
11218      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11219
11220      // if P == '0' && W == '1' then UNPREDICTABLE;
11221      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11222        return false;
11223
11224      // if t2 == 15 || m == 15 then UNPREDICTABLE;
11225      if ((t2 == 15) || (m == 15))
11226        return false;
11227
11228      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11229      if (wback && ((n == 15) || (n == t) || (n == t2)))
11230        return false;
11231
11232      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11233      if ((ArchVersion() < 6) && wback && (m == n))
11234        return false;
11235
11236      break;
11237
11238    default:
11239      return false;
11240    }
11241
11242    RegisterInfo base_reg;
11243    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11244    RegisterInfo offset_reg;
11245    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11246    RegisterInfo data_reg;
11247
11248    uint32_t Rn = ReadCoreReg(n, &success);
11249    if (!success)
11250      return false;
11251
11252    uint32_t Rm = ReadCoreReg(m, &success);
11253    if (!success)
11254      return false;
11255
11256    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11257    addr_t offset_addr;
11258    if (add)
11259      offset_addr = Rn + Rm;
11260    else
11261      offset_addr = Rn - Rm;
11262
11263    // address = if index then offset_addr else R[n];
11264    addr_t address;
11265    if (index)
11266      address = offset_addr;
11267    else
11268      address = Rn;
11269    // MemA[address,4] = R[t];
11270    uint32_t Rt = ReadCoreReg(t, &success);
11271    if (!success)
11272      return false;
11273
11274    EmulateInstruction::Context context;
11275    if (t == 13)
11276      context.type = eContextPushRegisterOnStack;
11277    else
11278      context.type = eContextRegisterStore;
11279
11280    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11281    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11282                                                    data_reg);
11283
11284    const uint32_t addr_byte_size = GetAddressByteSize();
11285
11286    if (!MemAWrite(context, address, Rt, addr_byte_size))
11287      return false;
11288
11289    // MemA[address+4,4] = R[t2];
11290    uint32_t Rt2 = ReadCoreReg(t2, &success);
11291    if (!success)
11292      return false;
11293
11294    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11295
11296    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11297                                                    data_reg);
11298
11299    if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11300      return false;
11301
11302    // if wback then R[n] = offset_addr;
11303    if (wback) {
11304      context.type = eContextAdjustBaseRegister;
11305      context.SetAddress(offset_addr);
11306
11307      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11308                                 offset_addr))
11309        return false;
11310    }
11311  }
11312  return true;
11313}
11314
11315// A8.6.319 VLDM
11316// Vector Load Multiple loads multiple extension registers from consecutive
11317// memory locations using an address from
11318// an ARM core register.
11319bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11320                                        const ARMEncoding encoding) {
11321#if 0
11322    if ConditionPassed() then
11323        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11324        address = if add then R[n] else R[n]-imm32;
11325        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11326        for r = 0 to regs-1
11327            if single_regs then
11328                S[d+r] = MemA[address,4]; address = address+4;
11329            else
11330                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11331                // Combine the word-aligned words in the correct order for current endianness.
11332                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11333#endif
11334
11335  bool success = false;
11336
11337  if (ConditionPassed(opcode)) {
11338    bool single_regs;
11339    bool add;
11340    bool wback;
11341    uint32_t d;
11342    uint32_t n;
11343    uint32_t imm32;
11344    uint32_t regs;
11345
11346    switch (encoding) {
11347    case eEncodingT1:
11348    case eEncodingA1:
11349      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11350      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11351      // if P == '1' && W == '0' then SEE VLDR;
11352      // if P == U && W == '1' then UNDEFINED;
11353      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11354        return false;
11355
11356      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11357      // !), 101 (DB with !)
11358      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11359      single_regs = false;
11360      add = BitIsSet(opcode, 23);
11361      wback = BitIsSet(opcode, 21);
11362
11363      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11364      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11365      n = Bits32(opcode, 19, 16);
11366      imm32 = Bits32(opcode, 7, 0) << 2;
11367
11368      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11369      regs = Bits32(opcode, 7, 0) / 2;
11370
11371      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11372      // UNPREDICTABLE;
11373      if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11374        return false;
11375
11376      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11377      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11378        return false;
11379
11380      break;
11381
11382    case eEncodingT2:
11383    case eEncodingA2:
11384      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11385      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11386      // if P == '1' && W == '0' then SEE VLDR;
11387      // if P == U && W == '1' then UNDEFINED;
11388      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11389        return false;
11390
11391      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11392      // !), 101 (DB with !)
11393      // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
11394      // UInt(Vd:D); n = UInt(Rn);
11395      single_regs = true;
11396      add = BitIsSet(opcode, 23);
11397      wback = BitIsSet(opcode, 21);
11398      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11399      n = Bits32(opcode, 19, 16);
11400
11401      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11402      imm32 = Bits32(opcode, 7, 0) << 2;
11403      regs = Bits32(opcode, 7, 0);
11404
11405      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11406      // UNPREDICTABLE;
11407      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11408        return false;
11409
11410      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11411      if ((regs == 0) || ((d + regs) > 32))
11412        return false;
11413      break;
11414
11415    default:
11416      return false;
11417    }
11418
11419    RegisterInfo base_reg;
11420    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11421
11422    uint32_t Rn = ReadCoreReg(n, &success);
11423    if (!success)
11424      return false;
11425
11426    // address = if add then R[n] else R[n]-imm32;
11427    addr_t address;
11428    if (add)
11429      address = Rn;
11430    else
11431      address = Rn - imm32;
11432
11433    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11434    EmulateInstruction::Context context;
11435
11436    if (wback) {
11437      uint32_t value;
11438      if (add)
11439        value = Rn + imm32;
11440      else
11441        value = Rn - imm32;
11442
11443      context.type = eContextAdjustBaseRegister;
11444      context.SetImmediateSigned(value - Rn);
11445      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11446                                 value))
11447        return false;
11448    }
11449
11450    const uint32_t addr_byte_size = GetAddressByteSize();
11451    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11452
11453    context.type = eContextRegisterLoad;
11454
11455    // for r = 0 to regs-1
11456    for (uint32_t r = 0; r < regs; ++r) {
11457      if (single_regs) {
11458        // S[d+r] = MemA[address,4]; address = address+4;
11459        context.SetRegisterPlusOffset(base_reg, address - Rn);
11460
11461        uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11462        if (!success)
11463          return false;
11464
11465        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11466                                   start_reg + d + r, data))
11467          return false;
11468
11469        address = address + 4;
11470      } else {
11471        // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11472        // address+8;
11473        context.SetRegisterPlusOffset(base_reg, address - Rn);
11474        uint32_t word1 =
11475            MemARead(context, address, addr_byte_size, 0, &success);
11476        if (!success)
11477          return false;
11478
11479        context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11480        uint32_t word2 =
11481            MemARead(context, address + 4, addr_byte_size, 0, &success);
11482        if (!success)
11483          return false;
11484
11485        address = address + 8;
11486        // // Combine the word-aligned words in the correct order for current
11487        // endianness.
11488        // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11489        uint64_t data;
11490        if (GetByteOrder() == eByteOrderBig) {
11491          data = word1;
11492          data = (data << 32) | word2;
11493        } else {
11494          data = word2;
11495          data = (data << 32) | word1;
11496        }
11497
11498        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11499                                   start_reg + d + r, data))
11500          return false;
11501      }
11502    }
11503  }
11504  return true;
11505}
11506
11507// A8.6.399 VSTM
11508// Vector Store Multiple stores multiple extension registers to consecutive
11509// memory locations using an address from an
11510// ARM core register.
11511bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11512                                        const ARMEncoding encoding) {
11513#if 0
11514    if ConditionPassed() then
11515        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11516        address = if add then R[n] else R[n]-imm32;
11517        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11518        for r = 0 to regs-1
11519            if single_regs then
11520                MemA[address,4] = S[d+r]; address = address+4;
11521            else
11522                // Store as two word-aligned words in the correct order for current endianness.
11523                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11524                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11525                address = address+8;
11526#endif
11527
11528  bool success = false;
11529
11530  if (ConditionPassed(opcode)) {
11531    bool single_regs;
11532    bool add;
11533    bool wback;
11534    uint32_t d;
11535    uint32_t n;
11536    uint32_t imm32;
11537    uint32_t regs;
11538
11539    switch (encoding) {
11540    case eEncodingT1:
11541    case eEncodingA1:
11542      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11543      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11544      // if P == '1' && W == '0' then SEE VSTR;
11545      // if P == U && W == '1' then UNDEFINED;
11546      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11547        return false;
11548
11549      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11550      // !), 101 (DB with !)
11551      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11552      single_regs = false;
11553      add = BitIsSet(opcode, 23);
11554      wback = BitIsSet(opcode, 21);
11555
11556      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11557      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11558      n = Bits32(opcode, 19, 16);
11559      imm32 = Bits32(opcode, 7, 0) << 2;
11560
11561      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11562      regs = Bits32(opcode, 7, 0) / 2;
11563
11564      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11565      // UNPREDICTABLE;
11566      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11567        return false;
11568
11569      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11570      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11571        return false;
11572
11573      break;
11574
11575    case eEncodingT2:
11576    case eEncodingA2:
11577      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11578      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11579      // if P == '1' && W == '0' then SEE VSTR;
11580      // if P == U && W == '1' then UNDEFINED;
11581      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11582        return false;
11583
11584      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11585      // !), 101 (DB with !)
11586      // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
11587      // UInt(Vd:D); n = UInt(Rn);
11588      single_regs = true;
11589      add = BitIsSet(opcode, 23);
11590      wback = BitIsSet(opcode, 21);
11591      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11592      n = Bits32(opcode, 19, 16);
11593
11594      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11595      imm32 = Bits32(opcode, 7, 0) << 2;
11596      regs = Bits32(opcode, 7, 0);
11597
11598      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11599      // UNPREDICTABLE;
11600      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11601        return false;
11602
11603      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11604      if ((regs == 0) || ((d + regs) > 32))
11605        return false;
11606
11607      break;
11608
11609    default:
11610      return false;
11611    }
11612
11613    RegisterInfo base_reg;
11614    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11615
11616    uint32_t Rn = ReadCoreReg(n, &success);
11617    if (!success)
11618      return false;
11619
11620    // address = if add then R[n] else R[n]-imm32;
11621    addr_t address;
11622    if (add)
11623      address = Rn;
11624    else
11625      address = Rn - imm32;
11626
11627    EmulateInstruction::Context context;
11628    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11629    if (wback) {
11630      uint32_t value;
11631      if (add)
11632        value = Rn + imm32;
11633      else
11634        value = Rn - imm32;
11635
11636      context.type = eContextAdjustBaseRegister;
11637      context.SetRegisterPlusOffset(base_reg, value - Rn);
11638
11639      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11640                                 value))
11641        return false;
11642    }
11643
11644    const uint32_t addr_byte_size = GetAddressByteSize();
11645    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11646
11647    context.type = eContextRegisterStore;
11648    // for r = 0 to regs-1
11649    for (uint32_t r = 0; r < regs; ++r) {
11650
11651      if (single_regs) {
11652        // MemA[address,4] = S[d+r]; address = address+4;
11653        uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11654                                             start_reg + d + r, 0, &success);
11655        if (!success)
11656          return false;
11657
11658        RegisterInfo data_reg;
11659        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11660        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11661                                                address - Rn);
11662        if (!MemAWrite(context, address, data, addr_byte_size))
11663          return false;
11664
11665        address = address + 4;
11666      } else {
11667        // // Store as two word-aligned words in the correct order for current
11668        // endianness.
11669        // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11670        // D[d+r]<31:0>;
11671        // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11672        // D[d+r]<63:32>;
11673        uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11674                                             start_reg + d + r, 0, &success);
11675        if (!success)
11676          return false;
11677
11678        RegisterInfo data_reg;
11679        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11680
11681        if (GetByteOrder() == eByteOrderBig) {
11682          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11683                                                  address - Rn);
11684          if (!MemAWrite(context, address, Bits64(data, 63, 32),
11685                         addr_byte_size))
11686            return false;
11687
11688          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11689                                                  (address + 4) - Rn);
11690          if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11691                         addr_byte_size))
11692            return false;
11693        } else {
11694          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11695                                                  address - Rn);
11696          if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11697            return false;
11698
11699          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11700                                                  (address + 4) - Rn);
11701          if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11702                         addr_byte_size))
11703            return false;
11704        }
11705        // address = address+8;
11706        address = address + 8;
11707      }
11708    }
11709  }
11710  return true;
11711}
11712
11713// A8.6.320
11714// This instruction loads a single extension register from memory, using an
11715// address from an ARM core register, with
11716// an optional offset.
11717bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11718                                        ARMEncoding encoding) {
11719#if 0
11720    if ConditionPassed() then
11721        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11722        base = if n == 15 then Align(PC,4) else R[n];
11723        address = if add then (base + imm32) else (base - imm32);
11724        if single_reg then
11725            S[d] = MemA[address,4];
11726        else
11727            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11728            // Combine the word-aligned words in the correct order for current endianness.
11729            D[d] = if BigEndian() then word1:word2 else word2:word1;
11730#endif
11731
11732  bool success = false;
11733
11734  if (ConditionPassed(opcode)) {
11735    bool single_reg;
11736    bool add;
11737    uint32_t imm32;
11738    uint32_t d;
11739    uint32_t n;
11740
11741    switch (encoding) {
11742    case eEncodingT1:
11743    case eEncodingA1:
11744      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11745      // 32);
11746      single_reg = false;
11747      add = BitIsSet(opcode, 23);
11748      imm32 = Bits32(opcode, 7, 0) << 2;
11749
11750      // d = UInt(D:Vd); n = UInt(Rn);
11751      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11752      n = Bits32(opcode, 19, 16);
11753
11754      break;
11755
11756    case eEncodingT2:
11757    case eEncodingA2:
11758      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11759      single_reg = true;
11760      add = BitIsSet(opcode, 23);
11761      imm32 = Bits32(opcode, 7, 0) << 2;
11762
11763      // d = UInt(Vd:D); n = UInt(Rn);
11764      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11765      n = Bits32(opcode, 19, 16);
11766
11767      break;
11768
11769    default:
11770      return false;
11771    }
11772    RegisterInfo base_reg;
11773    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11774
11775    uint32_t Rn = ReadCoreReg(n, &success);
11776    if (!success)
11777      return false;
11778
11779    // base = if n == 15 then Align(PC,4) else R[n];
11780    uint32_t base;
11781    if (n == 15)
11782      base = AlignPC(Rn);
11783    else
11784      base = Rn;
11785
11786    // address = if add then (base + imm32) else (base - imm32);
11787    addr_t address;
11788    if (add)
11789      address = base + imm32;
11790    else
11791      address = base - imm32;
11792
11793    const uint32_t addr_byte_size = GetAddressByteSize();
11794    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11795
11796    EmulateInstruction::Context context;
11797    context.type = eContextRegisterLoad;
11798    context.SetRegisterPlusOffset(base_reg, address - base);
11799
11800    if (single_reg) {
11801      // S[d] = MemA[address,4];
11802      uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11803      if (!success)
11804        return false;
11805
11806      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11807                                 data))
11808        return false;
11809    } else {
11810      // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11811      uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11812      if (!success)
11813        return false;
11814
11815      context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11816      uint32_t word2 =
11817          MemARead(context, address + 4, addr_byte_size, 0, &success);
11818      if (!success)
11819        return false;
11820      // // Combine the word-aligned words in the correct order for current
11821      // endianness.
11822      // D[d] = if BigEndian() then word1:word2 else word2:word1;
11823      uint64_t data64;
11824      if (GetByteOrder() == eByteOrderBig) {
11825        data64 = word1;
11826        data64 = (data64 << 32) | word2;
11827      } else {
11828        data64 = word2;
11829        data64 = (data64 << 32) | word1;
11830      }
11831
11832      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11833                                 data64))
11834        return false;
11835    }
11836  }
11837  return true;
11838}
11839
11840// A8.6.400 VSTR
11841// This instruction stores a signle extension register to memory, using an
11842// address from an ARM core register, with an
11843// optional offset.
11844bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11845                                        ARMEncoding encoding) {
11846#if 0
11847    if ConditionPassed() then
11848        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11849        address = if add then (R[n] + imm32) else (R[n] - imm32);
11850        if single_reg then
11851            MemA[address,4] = S[d];
11852        else
11853            // Store as two word-aligned words in the correct order for current endianness.
11854            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11855            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11856#endif
11857
11858  bool success = false;
11859
11860  if (ConditionPassed(opcode)) {
11861    bool single_reg;
11862    bool add;
11863    uint32_t imm32;
11864    uint32_t d;
11865    uint32_t n;
11866
11867    switch (encoding) {
11868    case eEncodingT1:
11869    case eEncodingA1:
11870      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11871      // 32);
11872      single_reg = false;
11873      add = BitIsSet(opcode, 23);
11874      imm32 = Bits32(opcode, 7, 0) << 2;
11875
11876      // d = UInt(D:Vd); n = UInt(Rn);
11877      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11878      n = Bits32(opcode, 19, 16);
11879
11880      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11881      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11882        return false;
11883
11884      break;
11885
11886    case eEncodingT2:
11887    case eEncodingA2:
11888      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11889      single_reg = true;
11890      add = BitIsSet(opcode, 23);
11891      imm32 = Bits32(opcode, 7, 0) << 2;
11892
11893      // d = UInt(Vd:D); n = UInt(Rn);
11894      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11895      n = Bits32(opcode, 19, 16);
11896
11897      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11898      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11899        return false;
11900
11901      break;
11902
11903    default:
11904      return false;
11905    }
11906
11907    RegisterInfo base_reg;
11908    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11909
11910    uint32_t Rn = ReadCoreReg(n, &success);
11911    if (!success)
11912      return false;
11913
11914    // address = if add then (R[n] + imm32) else (R[n] - imm32);
11915    addr_t address;
11916    if (add)
11917      address = Rn + imm32;
11918    else
11919      address = Rn - imm32;
11920
11921    const uint32_t addr_byte_size = GetAddressByteSize();
11922    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11923
11924    RegisterInfo data_reg;
11925    GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11926    EmulateInstruction::Context context;
11927    context.type = eContextRegisterStore;
11928    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11929
11930    if (single_reg) {
11931      // MemA[address,4] = S[d];
11932      uint32_t data =
11933          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11934      if (!success)
11935        return false;
11936
11937      if (!MemAWrite(context, address, data, addr_byte_size))
11938        return false;
11939    } else {
11940      // // Store as two word-aligned words in the correct order for current
11941      // endianness.
11942      // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11943      // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11944      uint64_t data =
11945          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11946      if (!success)
11947        return false;
11948
11949      if (GetByteOrder() == eByteOrderBig) {
11950        if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11951          return false;
11952
11953        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11954                                                (address + 4) - Rn);
11955        if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11956                       addr_byte_size))
11957          return false;
11958      } else {
11959        if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11960          return false;
11961
11962        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11963                                                (address + 4) - Rn);
11964        if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11965                       addr_byte_size))
11966          return false;
11967      }
11968    }
11969  }
11970  return true;
11971}
11972
11973// A8.6.307 VLDI1 (multiple single elements)
11974// This instruction loads elements from memory into one, two, three or four
11975// registers, without de-interleaving.  Every
11976// element of each register is loaded.
11977bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11978                                                ARMEncoding encoding) {
11979#if 0
11980    if ConditionPassed() then
11981        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11982        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11983        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11984        for r = 0 to regs-1
11985            for e = 0 to elements-1
11986                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11987                address = address + ebytes;
11988#endif
11989
11990  bool success = false;
11991
11992  if (ConditionPassed(opcode)) {
11993    uint32_t regs;
11994    uint32_t alignment;
11995    uint32_t ebytes;
11996    uint32_t esize;
11997    uint32_t elements;
11998    uint32_t d;
11999    uint32_t n;
12000    uint32_t m;
12001    bool wback;
12002    bool register_index;
12003
12004    switch (encoding) {
12005    case eEncodingT1:
12006    case eEncodingA1: {
12007      // case type of
12008      // when '0111'
12009      // regs = 1; if align<1> == '1' then UNDEFINED;
12010      // when '1010'
12011      // regs = 2; if align == '11' then UNDEFINED;
12012      // when '0110'
12013      // regs = 3; if align<1> == '1' then UNDEFINED;
12014      // when '0010'
12015      // regs = 4;
12016      // otherwise
12017      // SEE 'Related encodings';
12018      uint32_t type = Bits32(opcode, 11, 8);
12019      uint32_t align = Bits32(opcode, 5, 4);
12020      if (type == 7) // '0111'
12021      {
12022        regs = 1;
12023        if (BitIsSet(align, 1))
12024          return false;
12025      } else if (type == 10) // '1010'
12026      {
12027        regs = 2;
12028        if (align == 3)
12029          return false;
12030
12031      } else if (type == 6) // '0110'
12032      {
12033        regs = 3;
12034        if (BitIsSet(align, 1))
12035          return false;
12036      } else if (type == 2) // '0010'
12037      {
12038        regs = 4;
12039      } else
12040        return false;
12041
12042      // alignment = if align == '00' then 1 else 4 << UInt(align);
12043      if (align == 0)
12044        alignment = 1;
12045      else
12046        alignment = 4 << align;
12047
12048      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12049      ebytes = 1 << Bits32(opcode, 7, 6);
12050      esize = 8 * ebytes;
12051      elements = 8 / ebytes;
12052
12053      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12054      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12055      n = Bits32(opcode, 19, 15);
12056      m = Bits32(opcode, 3, 0);
12057
12058      // wback = (m != 15); register_index = (m != 15 && m != 13);
12059      wback = (m != 15);
12060      register_index = ((m != 15) && (m != 13));
12061
12062      // if d+regs > 32 then UNPREDICTABLE;
12063      if ((d + regs) > 32)
12064        return false;
12065    } break;
12066
12067    default:
12068      return false;
12069    }
12070
12071    RegisterInfo base_reg;
12072    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12073
12074    uint32_t Rn = ReadCoreReg(n, &success);
12075    if (!success)
12076      return false;
12077
12078    // address = R[n]; if (address MOD alignment) != 0 then
12079    // GenerateAlignmentException();
12080    addr_t address = Rn;
12081    if ((address % alignment) != 0)
12082      return false;
12083
12084    EmulateInstruction::Context context;
12085    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12086    if (wback) {
12087      uint32_t Rm = ReadCoreReg(m, &success);
12088      if (!success)
12089        return false;
12090
12091      uint32_t offset;
12092      if (register_index)
12093        offset = Rm;
12094      else
12095        offset = 8 * regs;
12096
12097      uint32_t value = Rn + offset;
12098      context.type = eContextAdjustBaseRegister;
12099      context.SetRegisterPlusOffset(base_reg, offset);
12100
12101      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12102                                 value))
12103        return false;
12104    }
12105
12106    // for r = 0 to regs-1
12107    for (uint32_t r = 0; r < regs; ++r) {
12108      // for e = 0 to elements-1
12109      uint64_t assembled_data = 0;
12110      for (uint32_t e = 0; e < elements; ++e) {
12111        // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12112        context.type = eContextRegisterLoad;
12113        context.SetRegisterPlusOffset(base_reg, address - Rn);
12114        uint64_t data = MemURead(context, address, ebytes, 0, &success);
12115        if (!success)
12116          return false;
12117
12118        assembled_data =
12119            (data << (e * esize)) |
12120            assembled_data; // New data goes to the left of existing data
12121
12122        // address = address + ebytes;
12123        address = address + ebytes;
12124      }
12125      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12126                                 assembled_data))
12127        return false;
12128    }
12129  }
12130  return true;
12131}
12132
12133// A8.6.308 VLD1 (single element to one lane)
12134//
12135bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12136                                              const ARMEncoding encoding) {
12137#if 0
12138    if ConditionPassed() then
12139        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12140        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12141        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12142        Elem[D[d],index,esize] = MemU[address,ebytes];
12143#endif
12144
12145  bool success = false;
12146
12147  if (ConditionPassed(opcode)) {
12148    uint32_t ebytes;
12149    uint32_t esize;
12150    uint32_t index;
12151    uint32_t alignment;
12152    uint32_t d;
12153    uint32_t n;
12154    uint32_t m;
12155    bool wback;
12156    bool register_index;
12157
12158    switch (encoding) {
12159    case eEncodingT1:
12160    case eEncodingA1: {
12161      uint32_t size = Bits32(opcode, 11, 10);
12162      uint32_t index_align = Bits32(opcode, 7, 4);
12163      // if size == '11' then SEE VLD1 (single element to all lanes);
12164      if (size == 3)
12165        return EmulateVLD1SingleAll(opcode, encoding);
12166      // case size of
12167      if (size == 0) // when '00'
12168      {
12169        // if index_align<0> != '0' then UNDEFINED;
12170        if (BitIsClear(index_align, 0))
12171          return false;
12172
12173        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12174        ebytes = 1;
12175        esize = 8;
12176        index = Bits32(index_align, 3, 1);
12177        alignment = 1;
12178      } else if (size == 1) // when '01'
12179      {
12180        // if index_align<1> != '0' then UNDEFINED;
12181        if (BitIsClear(index_align, 1))
12182          return false;
12183
12184        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12185        ebytes = 2;
12186        esize = 16;
12187        index = Bits32(index_align, 3, 2);
12188
12189        // alignment = if index_align<0> == '0' then 1 else 2;
12190        if (BitIsClear(index_align, 0))
12191          alignment = 1;
12192        else
12193          alignment = 2;
12194      } else if (size == 2) // when '10'
12195      {
12196        // if index_align<2> != '0' then UNDEFINED;
12197        if (BitIsClear(index_align, 2))
12198          return false;
12199
12200        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12201        // UNDEFINED;
12202        if ((Bits32(index_align, 1, 0) != 0) &&
12203            (Bits32(index_align, 1, 0) != 3))
12204          return false;
12205
12206        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12207        ebytes = 4;
12208        esize = 32;
12209        index = Bit32(index_align, 3);
12210
12211        // alignment = if index_align<1:0> == '00' then 1 else 4;
12212        if (Bits32(index_align, 1, 0) == 0)
12213          alignment = 1;
12214        else
12215          alignment = 4;
12216      } else {
12217        return false;
12218      }
12219      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12220      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12221      n = Bits32(opcode, 19, 16);
12222      m = Bits32(opcode, 3, 0);
12223
12224      // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12225      // then UNPREDICTABLE;
12226      wback = (m != 15);
12227      register_index = ((m != 15) && (m != 13));
12228
12229      if (n == 15)
12230        return false;
12231
12232    } break;
12233
12234    default:
12235      return false;
12236    }
12237
12238    RegisterInfo base_reg;
12239    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12240
12241    uint32_t Rn = ReadCoreReg(n, &success);
12242    if (!success)
12243      return false;
12244
12245    // address = R[n]; if (address MOD alignment) != 0 then
12246    // GenerateAlignmentException();
12247    addr_t address = Rn;
12248    if ((address % alignment) != 0)
12249      return false;
12250
12251    EmulateInstruction::Context context;
12252    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12253    if (wback) {
12254      uint32_t Rm = ReadCoreReg(m, &success);
12255      if (!success)
12256        return false;
12257
12258      uint32_t offset;
12259      if (register_index)
12260        offset = Rm;
12261      else
12262        offset = ebytes;
12263
12264      uint32_t value = Rn + offset;
12265
12266      context.type = eContextAdjustBaseRegister;
12267      context.SetRegisterPlusOffset(base_reg, offset);
12268
12269      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12270                                 value))
12271        return false;
12272    }
12273
12274    // Elem[D[d],index,esize] = MemU[address,ebytes];
12275    uint32_t element = MemURead(context, address, esize, 0, &success);
12276    if (!success)
12277      return false;
12278
12279    element = element << (index * esize);
12280
12281    uint64_t reg_data =
12282        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12283    if (!success)
12284      return false;
12285
12286    uint64_t all_ones = -1;
12287    uint64_t mask = all_ones
12288                    << ((index + 1) * esize); // mask is all 1's to left of
12289                                              // where 'element' goes, & all 0's
12290    // at element & to the right of element.
12291    if (index > 0)
12292      mask = mask | Bits64(all_ones, (index * esize) - 1,
12293                           0); // add 1's to the right of where 'element' goes.
12294    // now mask should be 0's where element goes & 1's
12295    // everywhere else.
12296
12297    uint64_t masked_reg =
12298        reg_data & mask; // Take original reg value & zero out 'element' bits
12299    reg_data =
12300        masked_reg & element; // Put 'element' into those bits in reg_data.
12301
12302    context.type = eContextRegisterLoad;
12303    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12304                               reg_data))
12305      return false;
12306  }
12307  return true;
12308}
12309
12310// A8.6.391 VST1 (multiple single elements)
12311// Vector Store (multiple single elements) stores elements to memory from one,
12312// two, three, or four registers, without
12313// interleaving.  Every element of each register is stored.
12314bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12315                                                ARMEncoding encoding) {
12316#if 0
12317    if ConditionPassed() then
12318        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12319        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12320        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12321        for r = 0 to regs-1
12322            for e = 0 to elements-1
12323                MemU[address,ebytes] = Elem[D[d+r],e,esize];
12324                address = address + ebytes;
12325#endif
12326
12327  bool success = false;
12328
12329  if (ConditionPassed(opcode)) {
12330    uint32_t regs;
12331    uint32_t alignment;
12332    uint32_t ebytes;
12333    uint32_t esize;
12334    uint32_t elements;
12335    uint32_t d;
12336    uint32_t n;
12337    uint32_t m;
12338    bool wback;
12339    bool register_index;
12340
12341    switch (encoding) {
12342    case eEncodingT1:
12343    case eEncodingA1: {
12344      uint32_t type = Bits32(opcode, 11, 8);
12345      uint32_t align = Bits32(opcode, 5, 4);
12346
12347      // case type of
12348      if (type == 7) // when '0111'
12349      {
12350        // regs = 1; if align<1> == '1' then UNDEFINED;
12351        regs = 1;
12352        if (BitIsSet(align, 1))
12353          return false;
12354      } else if (type == 10) // when '1010'
12355      {
12356        // regs = 2; if align == '11' then UNDEFINED;
12357        regs = 2;
12358        if (align == 3)
12359          return false;
12360      } else if (type == 6) // when '0110'
12361      {
12362        // regs = 3; if align<1> == '1' then UNDEFINED;
12363        regs = 3;
12364        if (BitIsSet(align, 1))
12365          return false;
12366      } else if (type == 2) // when '0010'
12367        // regs = 4;
12368        regs = 4;
12369      else // otherwise
12370        // SEE 'Related encodings';
12371        return false;
12372
12373      // alignment = if align == '00' then 1 else 4 << UInt(align);
12374      if (align == 0)
12375        alignment = 1;
12376      else
12377        alignment = 4 << align;
12378
12379      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12380      ebytes = 1 << Bits32(opcode, 7, 6);
12381      esize = 8 * ebytes;
12382      elements = 8 / ebytes;
12383
12384      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12385      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12386      n = Bits32(opcode, 19, 16);
12387      m = Bits32(opcode, 3, 0);
12388
12389      // wback = (m != 15); register_index = (m != 15 && m != 13);
12390      wback = (m != 15);
12391      register_index = ((m != 15) && (m != 13));
12392
12393      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12394      if ((d + regs) > 32)
12395        return false;
12396
12397      if (n == 15)
12398        return false;
12399
12400    } break;
12401
12402    default:
12403      return false;
12404    }
12405
12406    RegisterInfo base_reg;
12407    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12408
12409    uint32_t Rn = ReadCoreReg(n, &success);
12410    if (!success)
12411      return false;
12412
12413    // address = R[n]; if (address MOD alignment) != 0 then
12414    // GenerateAlignmentException();
12415    addr_t address = Rn;
12416    if ((address % alignment) != 0)
12417      return false;
12418
12419    EmulateInstruction::Context context;
12420    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12421    if (wback) {
12422      uint32_t Rm = ReadCoreReg(m, &success);
12423      if (!success)
12424        return false;
12425
12426      uint32_t offset;
12427      if (register_index)
12428        offset = Rm;
12429      else
12430        offset = 8 * regs;
12431
12432      context.type = eContextAdjustBaseRegister;
12433      context.SetRegisterPlusOffset(base_reg, offset);
12434
12435      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12436                                 Rn + offset))
12437        return false;
12438    }
12439
12440    RegisterInfo data_reg;
12441    context.type = eContextRegisterStore;
12442    // for r = 0 to regs-1
12443    for (uint32_t r = 0; r < regs; ++r) {
12444      GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12445      uint64_t register_data = ReadRegisterUnsigned(
12446          eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12447      if (!success)
12448        return false;
12449
12450      // for e = 0 to elements-1
12451      for (uint32_t e = 0; e < elements; ++e) {
12452        // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12453        uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12454
12455        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12456                                                address - Rn);
12457        if (!MemUWrite(context, address, word, ebytes))
12458          return false;
12459
12460        // address = address + ebytes;
12461        address = address + ebytes;
12462      }
12463    }
12464  }
12465  return true;
12466}
12467
12468// A8.6.392 VST1 (single element from one lane)
12469// This instruction stores one element to memory from one element of a register.
12470bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12471                                              ARMEncoding encoding) {
12472#if 0
12473    if ConditionPassed() then
12474        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12475        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12476        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12477        MemU[address,ebytes] = Elem[D[d],index,esize];
12478#endif
12479
12480  bool success = false;
12481
12482  if (ConditionPassed(opcode)) {
12483    uint32_t ebytes;
12484    uint32_t esize;
12485    uint32_t index;
12486    uint32_t alignment;
12487    uint32_t d;
12488    uint32_t n;
12489    uint32_t m;
12490    bool wback;
12491    bool register_index;
12492
12493    switch (encoding) {
12494    case eEncodingT1:
12495    case eEncodingA1: {
12496      uint32_t size = Bits32(opcode, 11, 10);
12497      uint32_t index_align = Bits32(opcode, 7, 4);
12498
12499      // if size == '11' then UNDEFINED;
12500      if (size == 3)
12501        return false;
12502
12503      // case size of
12504      if (size == 0) // when '00'
12505      {
12506        // if index_align<0> != '0' then UNDEFINED;
12507        if (BitIsClear(index_align, 0))
12508          return false;
12509        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12510        ebytes = 1;
12511        esize = 8;
12512        index = Bits32(index_align, 3, 1);
12513        alignment = 1;
12514      } else if (size == 1) // when '01'
12515      {
12516        // if index_align<1> != '0' then UNDEFINED;
12517        if (BitIsClear(index_align, 1))
12518          return false;
12519
12520        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12521        ebytes = 2;
12522        esize = 16;
12523        index = Bits32(index_align, 3, 2);
12524
12525        // alignment = if index_align<0> == '0' then 1 else 2;
12526        if (BitIsClear(index_align, 0))
12527          alignment = 1;
12528        else
12529          alignment = 2;
12530      } else if (size == 2) // when '10'
12531      {
12532        // if index_align<2> != '0' then UNDEFINED;
12533        if (BitIsClear(index_align, 2))
12534          return false;
12535
12536        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12537        // UNDEFINED;
12538        if ((Bits32(index_align, 1, 0) != 0) &&
12539            (Bits32(index_align, 1, 0) != 3))
12540          return false;
12541
12542        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12543        ebytes = 4;
12544        esize = 32;
12545        index = Bit32(index_align, 3);
12546
12547        // alignment = if index_align<1:0> == '00' then 1 else 4;
12548        if (Bits32(index_align, 1, 0) == 0)
12549          alignment = 1;
12550        else
12551          alignment = 4;
12552      } else {
12553        return false;
12554      }
12555      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12556      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12557      n = Bits32(opcode, 19, 16);
12558      m = Bits32(opcode, 3, 0);
12559
12560      // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12561      // then UNPREDICTABLE;
12562      wback = (m != 15);
12563      register_index = ((m != 15) && (m != 13));
12564
12565      if (n == 15)
12566        return false;
12567    } break;
12568
12569    default:
12570      return false;
12571    }
12572
12573    RegisterInfo base_reg;
12574    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12575
12576    uint32_t Rn = ReadCoreReg(n, &success);
12577    if (!success)
12578      return false;
12579
12580    // address = R[n]; if (address MOD alignment) != 0 then
12581    // GenerateAlignmentException();
12582    addr_t address = Rn;
12583    if ((address % alignment) != 0)
12584      return false;
12585
12586    EmulateInstruction::Context context;
12587    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12588    if (wback) {
12589      uint32_t Rm = ReadCoreReg(m, &success);
12590      if (!success)
12591        return false;
12592
12593      uint32_t offset;
12594      if (register_index)
12595        offset = Rm;
12596      else
12597        offset = ebytes;
12598
12599      context.type = eContextAdjustBaseRegister;
12600      context.SetRegisterPlusOffset(base_reg, offset);
12601
12602      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12603                                 Rn + offset))
12604        return false;
12605    }
12606
12607    // MemU[address,ebytes] = Elem[D[d],index,esize];
12608    uint64_t register_data =
12609        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12610    if (!success)
12611      return false;
12612
12613    uint64_t word =
12614        Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12615
12616    RegisterInfo data_reg;
12617    GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12618    context.type = eContextRegisterStore;
12619    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12620
12621    if (!MemUWrite(context, address, word, ebytes))
12622      return false;
12623  }
12624  return true;
12625}
12626
12627// A8.6.309 VLD1 (single element to all lanes)
12628// This instruction loads one element from memory into every element of one or
12629// two vectors.
12630bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12631                                                 const ARMEncoding encoding) {
12632#if 0
12633    if ConditionPassed() then
12634        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12635        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12636        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12637        replicated_element = Replicate(MemU[address,ebytes], elements);
12638        for r = 0 to regs-1
12639            D[d+r] = replicated_element;
12640#endif
12641
12642  bool success = false;
12643
12644  if (ConditionPassed(opcode)) {
12645    uint32_t ebytes;
12646    uint32_t elements;
12647    uint32_t regs;
12648    uint32_t alignment;
12649    uint32_t d;
12650    uint32_t n;
12651    uint32_t m;
12652    bool wback;
12653    bool register_index;
12654
12655    switch (encoding) {
12656    case eEncodingT1:
12657    case eEncodingA1: {
12658      // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12659      uint32_t size = Bits32(opcode, 7, 6);
12660      if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12661        return false;
12662
12663      // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12664      // then 1 else 2;
12665      ebytes = 1 << size;
12666      elements = 8 / ebytes;
12667      if (BitIsClear(opcode, 5))
12668        regs = 1;
12669      else
12670        regs = 2;
12671
12672      // alignment = if a == '0' then 1 else ebytes;
12673      if (BitIsClear(opcode, 4))
12674        alignment = 1;
12675      else
12676        alignment = ebytes;
12677
12678      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12679      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12680      n = Bits32(opcode, 19, 16);
12681      m = Bits32(opcode, 3, 0);
12682
12683      // wback = (m != 15); register_index = (m != 15 && m != 13);
12684      wback = (m != 15);
12685      register_index = ((m != 15) && (m != 13));
12686
12687      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12688      if ((d + regs) > 32)
12689        return false;
12690
12691      if (n == 15)
12692        return false;
12693    } break;
12694
12695    default:
12696      return false;
12697    }
12698
12699    RegisterInfo base_reg;
12700    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12701
12702    uint32_t Rn = ReadCoreReg(n, &success);
12703    if (!success)
12704      return false;
12705
12706    // address = R[n]; if (address MOD alignment) != 0 then
12707    // GenerateAlignmentException();
12708    addr_t address = Rn;
12709    if ((address % alignment) != 0)
12710      return false;
12711
12712    EmulateInstruction::Context context;
12713    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12714    if (wback) {
12715      uint32_t Rm = ReadCoreReg(m, &success);
12716      if (!success)
12717        return false;
12718
12719      uint32_t offset;
12720      if (register_index)
12721        offset = Rm;
12722      else
12723        offset = ebytes;
12724
12725      context.type = eContextAdjustBaseRegister;
12726      context.SetRegisterPlusOffset(base_reg, offset);
12727
12728      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12729                                 Rn + offset))
12730        return false;
12731    }
12732
12733    // replicated_element = Replicate(MemU[address,ebytes], elements);
12734
12735    context.type = eContextRegisterLoad;
12736    uint64_t word = MemURead(context, address, ebytes, 0, &success);
12737    if (!success)
12738      return false;
12739
12740    uint64_t replicated_element = 0;
12741    uint32_t esize = ebytes * 8;
12742    for (uint32_t e = 0; e < elements; ++e)
12743      replicated_element =
12744          (replicated_element << esize) | Bits64(word, esize - 1, 0);
12745
12746    // for r = 0 to regs-1
12747    for (uint32_t r = 0; r < regs; ++r) {
12748      // D[d+r] = replicated_element;
12749      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12750                                 replicated_element))
12751        return false;
12752    }
12753  }
12754  return true;
12755}
12756
12757// B6.2.13 SUBS PC, LR and related instructions
12758// The SUBS PC, LR, #<const? instruction provides an exception return without
12759// the use of the stack.  It subtracts the
12760// immediate constant from the LR, branches to the resulting address, and also
12761// copies the SPSR to the CPSR.
12762bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12763                                               const ARMEncoding encoding) {
12764#if 0
12765    if ConditionPassed() then
12766        EncodingSpecificOperations();
12767        if CurrentInstrSet() == InstrSet_ThumbEE then
12768            UNPREDICTABLE;
12769        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12770        case opcode of
12771            when '0000' result = R[n] AND operand2; // AND
12772            when '0001' result = R[n] EOR operand2; // EOR
12773            when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12774            when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12775            when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12776            when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12777            when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12778            when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12779            when '1100' result = R[n] OR operand2; // ORR
12780            when '1101' result = operand2; // MOV
12781            when '1110' result = R[n] AND NOT(operand2); // BIC
12782            when '1111' result = NOT(operand2); // MVN
12783        CPSRWriteByInstr(SPSR[], '1111', TRUE);
12784        BranchWritePC(result);
12785#endif
12786
12787  bool success = false;
12788
12789  if (ConditionPassed(opcode)) {
12790    uint32_t n;
12791    uint32_t m;
12792    uint32_t imm32;
12793    bool register_form;
12794    ARM_ShifterType shift_t;
12795    uint32_t shift_n;
12796    uint32_t code;
12797
12798    switch (encoding) {
12799    case eEncodingT1:
12800      // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12801      // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode =
12802      // '0010'; // = SUB
12803      n = 14;
12804      imm32 = Bits32(opcode, 7, 0);
12805      register_form = false;
12806      code = 2;
12807
12808      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12809      if (InITBlock() && !LastInITBlock())
12810        return false;
12811
12812      break;
12813
12814    case eEncodingA1:
12815      // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12816      n = Bits32(opcode, 19, 16);
12817      imm32 = ARMExpandImm(opcode);
12818      register_form = false;
12819      code = Bits32(opcode, 24, 21);
12820
12821      break;
12822
12823    case eEncodingA2:
12824      // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12825      n = Bits32(opcode, 19, 16);
12826      m = Bits32(opcode, 3, 0);
12827      register_form = true;
12828
12829      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12830      shift_n = DecodeImmShiftARM(opcode, shift_t);
12831
12832      break;
12833
12834    default:
12835      return false;
12836    }
12837
12838    // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12839    // else imm32;
12840    uint32_t operand2;
12841    if (register_form) {
12842      uint32_t Rm = ReadCoreReg(m, &success);
12843      if (!success)
12844        return false;
12845
12846      operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12847      if (!success)
12848        return false;
12849    } else {
12850      operand2 = imm32;
12851    }
12852
12853    uint32_t Rn = ReadCoreReg(n, &success);
12854    if (!success)
12855      return false;
12856
12857    AddWithCarryResult result;
12858
12859    // case opcode of
12860    switch (code) {
12861    case 0: // when '0000'
12862      // result = R[n] AND operand2; // AND
12863      result.result = Rn & operand2;
12864      break;
12865
12866    case 1: // when '0001'
12867      // result = R[n] EOR operand2; // EOR
12868      result.result = Rn ^ operand2;
12869      break;
12870
12871    case 2: // when '0010'
12872      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12873      result = AddWithCarry(Rn, ~(operand2), 1);
12874      break;
12875
12876    case 3: // when '0011'
12877      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12878      result = AddWithCarry(~(Rn), operand2, 1);
12879      break;
12880
12881    case 4: // when '0100'
12882      // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12883      result = AddWithCarry(Rn, operand2, 0);
12884      break;
12885
12886    case 5: // when '0101'
12887      // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12888      result = AddWithCarry(Rn, operand2, APSR_C);
12889      break;
12890
12891    case 6: // when '0110'
12892      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12893      result = AddWithCarry(Rn, ~(operand2), APSR_C);
12894      break;
12895
12896    case 7: // when '0111'
12897      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12898      result = AddWithCarry(~(Rn), operand2, APSR_C);
12899      break;
12900
12901    case 10: // when '1100'
12902      // result = R[n] OR operand2; // ORR
12903      result.result = Rn | operand2;
12904      break;
12905
12906    case 11: // when '1101'
12907      // result = operand2; // MOV
12908      result.result = operand2;
12909      break;
12910
12911    case 12: // when '1110'
12912      // result = R[n] AND NOT(operand2); // BIC
12913      result.result = Rn & ~(operand2);
12914      break;
12915
12916    case 15: // when '1111'
12917      // result = NOT(operand2); // MVN
12918      result.result = ~(operand2);
12919      break;
12920
12921    default:
12922      return false;
12923    }
12924    // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12925
12926    // For now, in emulation mode, we don't have access to the SPSR, so we will
12927    // use the CPSR instead, and hope for
12928    // the best.
12929    uint32_t spsr =
12930        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12931    if (!success)
12932      return false;
12933
12934    CPSRWriteByInstr(spsr, 15, true);
12935
12936    // BranchWritePC(result);
12937    EmulateInstruction::Context context;
12938    context.type = eContextAdjustPC;
12939    context.SetImmediate(result.result);
12940
12941    BranchWritePC(context, result.result);
12942  }
12943  return true;
12944}
12945
12946EmulateInstructionARM::ARMOpcode *
12947EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12948                                                  uint32_t arm_isa) {
12949  static ARMOpcode g_arm_opcodes[] = {
12950      //----------------------------------------------------------------------
12951      // Prologue instructions
12952      //----------------------------------------------------------------------
12953
12954      // push register(s)
12955      {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12956       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12957      {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12958       &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12959
12960      // set r7 to point to a stack offset
12961      {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12962       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12963      {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12964       &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12965      // copy the stack pointer to ip
12966      {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12967       &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12968      {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12969       &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12970      {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12971       &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12972
12973      // adjust the stack pointer
12974      {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12975       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12976      {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12977       &EmulateInstructionARM::EmulateSUBSPReg,
12978       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12979
12980      // push one register
12981      // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12982      {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12983       &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12984
12985      // vector push consecutive extension register(s)
12986      {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12987       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12988      {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12989       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12990
12991      //----------------------------------------------------------------------
12992      // Epilogue instructions
12993      //----------------------------------------------------------------------
12994
12995      {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12996       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12997      {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12998       &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12999      {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
13000       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13001      {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13002       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13003
13004      //----------------------------------------------------------------------
13005      // Supervisor Call (previously Software Interrupt)
13006      //----------------------------------------------------------------------
13007      {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13008       &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
13009
13010      //----------------------------------------------------------------------
13011      // Branch instructions
13012      //----------------------------------------------------------------------
13013      // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
13014      // "bl <label>".
13015      {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
13016       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13017      {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13018       &EmulateInstructionARM::EmulateB, "b #imm24"},
13019      {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13020       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13021      {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
13022       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13023      // for example, "bx lr"
13024      {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
13025       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13026      // bxj
13027      {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
13028       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13029
13030      //----------------------------------------------------------------------
13031      // Data-processing instructions
13032      //----------------------------------------------------------------------
13033      // adc (immediate)
13034      {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13035       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
13036      // adc (register)
13037      {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038       &EmulateInstructionARM::EmulateADCReg,
13039       "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13040      // add (immediate)
13041      {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13042       &EmulateInstructionARM::EmulateADDImmARM,
13043       "add{s}<c> <Rd>, <Rn>, #const"},
13044      // add (register)
13045      {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13046       &EmulateInstructionARM::EmulateADDReg,
13047       "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13048      // add (register-shifted register)
13049      {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13050       &EmulateInstructionARM::EmulateADDRegShift,
13051       "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
13052      // adr
13053      {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13054       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13055      {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13056       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13057      // and (immediate)
13058      {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
13060      // and (register)
13061      {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062       &EmulateInstructionARM::EmulateANDReg,
13063       "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13064      // bic (immediate)
13065      {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13066       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
13067      // bic (register)
13068      {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13069       &EmulateInstructionARM::EmulateBICReg,
13070       "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13071      // eor (immediate)
13072      {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13073       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
13074      // eor (register)
13075      {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13076       &EmulateInstructionARM::EmulateEORReg,
13077       "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13078      // orr (immediate)
13079      {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13080       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
13081      // orr (register)
13082      {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13083       &EmulateInstructionARM::EmulateORRReg,
13084       "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13085      // rsb (immediate)
13086      {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13087       &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
13088      // rsb (register)
13089      {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13090       &EmulateInstructionARM::EmulateRSBReg,
13091       "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13092      // rsc (immediate)
13093      {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13094       &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
13095      // rsc (register)
13096      {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13097       &EmulateInstructionARM::EmulateRSCReg,
13098       "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13099      // sbc (immediate)
13100      {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13101       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13102      // sbc (register)
13103      {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13104       &EmulateInstructionARM::EmulateSBCReg,
13105       "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
13106      // sub (immediate, ARM)
13107      {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13108       &EmulateInstructionARM::EmulateSUBImmARM,
13109       "sub{s}<c> <Rd>, <Rn>, #<const>"},
13110      // sub (sp minus immediate)
13111      {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13112       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13113      // sub (register)
13114      {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13115       &EmulateInstructionARM::EmulateSUBReg,
13116       "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13117      // teq (immediate)
13118      {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13119       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13120      // teq (register)
13121      {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13122       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13123      // tst (immediate)
13124      {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13125       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13126      // tst (register)
13127      {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13128       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13129
13130      // mov (immediate)
13131      {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13132       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13133      {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13134       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13135      // mov (register)
13136      {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13137       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13138      // mvn (immediate)
13139      {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13140       &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13141      // mvn (register)
13142      {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13143       &EmulateInstructionARM::EmulateMVNReg,
13144       "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13145      // cmn (immediate)
13146      {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13147       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13148      // cmn (register)
13149      {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13150       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13151      // cmp (immediate)
13152      {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13153       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13154      // cmp (register)
13155      {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13156       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13157      // asr (immediate)
13158      {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13159       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13160      // asr (register)
13161      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13162       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13163      // lsl (immediate)
13164      {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13165       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13166      // lsl (register)
13167      {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13168       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13169      // lsr (immediate)
13170      {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13171       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13172      // lsr (register)
13173      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13174       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13175      // rrx is a special case encoding of ror (immediate)
13176      {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13177       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13178      // ror (immediate)
13179      {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13180       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13181      // ror (register)
13182      {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13183       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13184      // mul
13185      {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13186       &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13187
13188      // subs pc, lr and related instructions
13189      {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13190       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13191       "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13192      {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13193       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13194       "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13195
13196      //----------------------------------------------------------------------
13197      // Load instructions
13198      //----------------------------------------------------------------------
13199      {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13200       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13201      {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13202       &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13203      {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13204       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13205      {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13206       &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13207      {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13208       &EmulateInstructionARM::EmulateLDRImmediateARM,
13209       "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13210      {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13211       &EmulateInstructionARM::EmulateLDRRegister,
13212       "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13213      {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13214       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13215      {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13216       &EmulateInstructionARM::EmulateLDRBRegister,
13217       "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13218      {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13219       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13220      {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13221       &EmulateInstructionARM::EmulateLDRHRegister,
13222       "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13223      {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13224       &EmulateInstructionARM::EmulateLDRSBImmediate,
13225       "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13226      {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13227       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13228      {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13229       &EmulateInstructionARM::EmulateLDRSBRegister,
13230       "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13231      {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13232       &EmulateInstructionARM::EmulateLDRSHImmediate,
13233       "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13234      {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13235       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13236      {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13237       &EmulateInstructionARM::EmulateLDRSHRegister,
13238       "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13239      {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13240       &EmulateInstructionARM::EmulateLDRDImmediate,
13241       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13242      {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13243       &EmulateInstructionARM::EmulateLDRDRegister,
13244       "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13245      {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13246       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13247      {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13248       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13249      {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13250       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13251      {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13252       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13253      {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13254       &EmulateInstructionARM::EmulateVLD1Multiple,
13255       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13256      {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13257       &EmulateInstructionARM::EmulateVLD1Single,
13258       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13259      {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13260       &EmulateInstructionARM::EmulateVLD1SingleAll,
13261       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13262
13263      //----------------------------------------------------------------------
13264      // Store instructions
13265      //----------------------------------------------------------------------
13266      {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13267       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13268      {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13269       &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13270      {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13271       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13272      {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13273       &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13274      {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13275       &EmulateInstructionARM::EmulateSTRRegister,
13276       "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13277      {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13278       &EmulateInstructionARM::EmulateSTRHRegister,
13279       "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13280      {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13281       &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13282      {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13283       &EmulateInstructionARM::EmulateSTRBImmARM,
13284       "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13285      {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13286       &EmulateInstructionARM::EmulateSTRImmARM,
13287       "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13288      {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13289       &EmulateInstructionARM::EmulateSTRDImm,
13290       "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13291      {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13292       &EmulateInstructionARM::EmulateSTRDReg,
13293       "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13294      {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13295       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13296      {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13297       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13298      {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13299       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13300      {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13301       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13302      {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13303       &EmulateInstructionARM::EmulateVST1Multiple,
13304       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13305      {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13306       &EmulateInstructionARM::EmulateVST1Single,
13307       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13308
13309      //----------------------------------------------------------------------
13310      // Other instructions
13311      //----------------------------------------------------------------------
13312      {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13313       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13314      {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13315       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13316      {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13317       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13318      {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13319       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13320      {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13321       &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13322
13323  };
13324  static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13325
13326  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13327    if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13328        (g_arm_opcodes[i].variants & arm_isa) != 0)
13329      return &g_arm_opcodes[i];
13330  }
13331  return NULL;
13332}
13333
13334EmulateInstructionARM::ARMOpcode *
13335EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13336                                                    uint32_t arm_isa) {
13337
13338  static ARMOpcode g_thumb_opcodes[] = {
13339      //----------------------------------------------------------------------
13340      // Prologue instructions
13341      //----------------------------------------------------------------------
13342
13343      // push register(s)
13344      {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13345       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13346      {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13347       &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13348      {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13349       &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13350
13351      // set r7 to point to a stack offset
13352      {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13353       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13354      // copy the stack pointer to r7
13355      {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13356       &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13357      // move from high register to low register (comes after "mov r7, sp" to
13358      // resolve ambiguity)
13359      {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13360       &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13361
13362      // PC-relative load into register (see also EmulateADDSPRm)
13363      {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13364       &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13365
13366      // adjust the stack pointer
13367      {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13368       &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13369      {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13370       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13371      {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13372       &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13373      {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13374       &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13375      {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13376       &EmulateInstructionARM::EmulateSUBSPReg,
13377       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13378
13379      // vector push consecutive extension register(s)
13380      {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13381       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13382      {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13383       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13384
13385      //----------------------------------------------------------------------
13386      // Epilogue instructions
13387      //----------------------------------------------------------------------
13388
13389      {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13390       &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13391      {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13392       &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13393      {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13394       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13395      {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13396       &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13397      {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13398       &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13399      {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13400       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13401      {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13402       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13403
13404      //----------------------------------------------------------------------
13405      // Supervisor Call (previously Software Interrupt)
13406      //----------------------------------------------------------------------
13407      {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13408       &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13409
13410      //----------------------------------------------------------------------
13411      // If Then makes up to four following instructions conditional.
13412      //----------------------------------------------------------------------
13413      // The next 5 opcode _must_ come before the if then instruction
13414      {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13415       &EmulateInstructionARM::EmulateNop, "nop"},
13416      {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13417       &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13418      {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13419       &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13420      {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13421       &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13422      {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13423       &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13424      {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13425       &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13426
13427      //----------------------------------------------------------------------
13428      // Branch instructions
13429      //----------------------------------------------------------------------
13430      // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13431      {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13432       &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13433      {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13434       &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13435      {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13436       &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13437      {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13438       &EmulateInstructionARM::EmulateB,
13439       "b<c>.w #imm8 (outside or last in IT)"},
13440      // J1 == J2 == 1
13441      {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13442       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13443      // J1 == J2 == 1
13444      {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13445       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13446      {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13447       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13448      // for example, "bx lr"
13449      {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13450       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13451      // bxj
13452      {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13453       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13454      // compare and branch
13455      {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13456       &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13457      // table branch byte
13458      {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13459       &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13460      // table branch halfword
13461      {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13462       &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13463
13464      //----------------------------------------------------------------------
13465      // Data-processing instructions
13466      //----------------------------------------------------------------------
13467      // adc (immediate)
13468      {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13469       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13470      // adc (register)
13471      {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13472       &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13473      {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13474       &EmulateInstructionARM::EmulateADCReg,
13475       "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13476      // add (register)
13477      {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13478       &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13479      // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13480      // ambiguity decoding the two.
13481      {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13482       &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13483      // adr
13484      {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13485       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13486      {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13487       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13488      {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13489       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13490      // and (immediate)
13491      {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13492       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13493      // and (register)
13494      {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13495       &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13496      {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13497       &EmulateInstructionARM::EmulateANDReg,
13498       "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13499      // bic (immediate)
13500      {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13501       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13502      // bic (register)
13503      {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13504       &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13505      {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13506       &EmulateInstructionARM::EmulateBICReg,
13507       "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13508      // eor (immediate)
13509      {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13510       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13511      // eor (register)
13512      {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13513       &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13514      {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13515       &EmulateInstructionARM::EmulateEORReg,
13516       "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13517      // orr (immediate)
13518      {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13519       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13520      // orr (register)
13521      {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13522       &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13523      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13524       &EmulateInstructionARM::EmulateORRReg,
13525       "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13526      // rsb (immediate)
13527      {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13528       &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13529      {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13530       &EmulateInstructionARM::EmulateRSBImm,
13531       "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13532      // rsb (register)
13533      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13534       &EmulateInstructionARM::EmulateRSBReg,
13535       "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13536      // sbc (immediate)
13537      {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13538       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13539      // sbc (register)
13540      {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13541       &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13542      {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13543       &EmulateInstructionARM::EmulateSBCReg,
13544       "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13545      // add (immediate, Thumb)
13546      {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13547       &EmulateInstructionARM::EmulateADDImmThumb,
13548       "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13549      {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13550       &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13551      {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13552       &EmulateInstructionARM::EmulateADDImmThumb,
13553       "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13554      {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13555       &EmulateInstructionARM::EmulateADDImmThumb,
13556       "addw<c> <Rd>,<Rn>,#<imm12>"},
13557      // sub (immediate, Thumb)
13558      {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13559       &EmulateInstructionARM::EmulateSUBImmThumb,
13560       "subs|sub<c> <Rd>, <Rn> #imm3"},
13561      {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13562       &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13563      {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13564       &EmulateInstructionARM::EmulateSUBImmThumb,
13565       "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13566      {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13567       &EmulateInstructionARM::EmulateSUBImmThumb,
13568       "subw<c> <Rd>, <Rn>, #imm12"},
13569      // sub (sp minus immediate)
13570      {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13571       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13572      {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13573       &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13574      // sub (register)
13575      {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13576       &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13577      {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13578       &EmulateInstructionARM::EmulateSUBReg,
13579       "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13580      // teq (immediate)
13581      {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13582       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13583      // teq (register)
13584      {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13585       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13586      // tst (immediate)
13587      {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13588       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13589      // tst (register)
13590      {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13591       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13592      {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13593       &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13594
13595      // move from high register to high register
13596      {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13597       &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13598      // move from low register to low register
13599      {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13600       &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13601      // mov{s}<c>.w <Rd>, <Rm>
13602      {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13603       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13604      // move immediate
13605      {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13606       &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13607      {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13608       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13609      {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13610       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13611      // mvn (immediate)
13612      {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13613       &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13614      // mvn (register)
13615      {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13616       &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13617      {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13618       &EmulateInstructionARM::EmulateMVNReg,
13619       "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13620      // cmn (immediate)
13621      {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13622       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13623      // cmn (register)
13624      {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13625       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13626      {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13627       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13628      // cmp (immediate)
13629      {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13630       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13631      {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13632       &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13633      // cmp (register) (Rn and Rm both from r0-r7)
13634      {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13635       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13636      // cmp (register) (Rn and Rm not both from r0-r7)
13637      {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13638       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13639      {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13640       &EmulateInstructionARM::EmulateCMPReg,
13641       "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13642      // asr (immediate)
13643      {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13644       &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13645      {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13646       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13647      // asr (register)
13648      {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13649       &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13650      {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13651       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13652      // lsl (immediate)
13653      {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13654       &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13655      {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13656       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13657      // lsl (register)
13658      {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13659       &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13660      {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13661       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13662      // lsr (immediate)
13663      {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13664       &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13665      {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13666       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13667      // lsr (register)
13668      {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13669       &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13670      {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13671       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13672      // rrx is a special case encoding of ror (immediate)
13673      {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13674       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13675      // ror (immediate)
13676      {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13677       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13678      // ror (register)
13679      {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13680       &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13681      {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13682       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13683      // mul
13684      {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13685       &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13686      // mul
13687      {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13688       &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13689
13690      // subs pc, lr and related instructions
13691      {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13692       &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13693
13694      //----------------------------------------------------------------------
13695      // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13696      // LDM.. Instructions in this table;
13697      // otherwise the wrong instructions will be selected.
13698      //----------------------------------------------------------------------
13699
13700      {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13701       &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13702      {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13703       &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13704
13705      //----------------------------------------------------------------------
13706      // Load instructions
13707      //----------------------------------------------------------------------
13708      {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13709       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13710      {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13711       &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13712      {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13713       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13714      {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13715       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13716      {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13717       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13718      {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13719       &EmulateInstructionARM::EmulateLDRRtRnImm,
13720       "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13721      {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13722       &EmulateInstructionARM::EmulateLDRRtRnImm,
13723       "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13724      // Thumb2 PC-relative load into register
13725      {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13726       &EmulateInstructionARM::EmulateLDRRtPCRelative,
13727       "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13728      {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13729       &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13730      {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13731       &EmulateInstructionARM::EmulateLDRRegister,
13732       "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13733      {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13734       &EmulateInstructionARM::EmulateLDRBImmediate,
13735       "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13736      {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13737       &EmulateInstructionARM::EmulateLDRBImmediate,
13738       "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13739      {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13740       &EmulateInstructionARM::EmulateLDRBImmediate,
13741       "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13742      {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13743       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13744      {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13745       &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13746      {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13747       &EmulateInstructionARM::EmulateLDRBRegister,
13748       "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13749      {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13750       &EmulateInstructionARM::EmulateLDRHImmediate,
13751       "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13752      {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13753       &EmulateInstructionARM::EmulateLDRHImmediate,
13754       "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13755      {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13756       &EmulateInstructionARM::EmulateLDRHImmediate,
13757       "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13758      {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13759       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13760      {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13761       &EmulateInstructionARM::EmulateLDRHRegister,
13762       "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13763      {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13764       &EmulateInstructionARM::EmulateLDRHRegister,
13765       "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13766      {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13767       &EmulateInstructionARM::EmulateLDRSBImmediate,
13768       "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13769      {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13770       &EmulateInstructionARM::EmulateLDRSBImmediate,
13771       "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13772      {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13773       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13774      {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13775       &EmulateInstructionARM::EmulateLDRSBRegister,
13776       "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13777      {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13778       &EmulateInstructionARM::EmulateLDRSBRegister,
13779       "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13780      {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13781       &EmulateInstructionARM::EmulateLDRSHImmediate,
13782       "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13783      {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13784       &EmulateInstructionARM::EmulateLDRSHImmediate,
13785       "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13786      {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13787       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13788      {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13789       &EmulateInstructionARM::EmulateLDRSHRegister,
13790       "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13791      {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13792       &EmulateInstructionARM::EmulateLDRSHRegister,
13793       "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13794      {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13795       &EmulateInstructionARM::EmulateLDRDImmediate,
13796       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13797      {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13798       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13799      {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13800       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13801      {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13802       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13803      {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13804       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13805      {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13806       &EmulateInstructionARM::EmulateVLD1Multiple,
13807       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13808      {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13809       &EmulateInstructionARM::EmulateVLD1Single,
13810       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13811      {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13812       &EmulateInstructionARM::EmulateVLD1SingleAll,
13813       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13814
13815      //----------------------------------------------------------------------
13816      // Store instructions
13817      //----------------------------------------------------------------------
13818      {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13819       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13820      {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13821       &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13822      {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13823       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13824      {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13825       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13826      {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13827       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13828      {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13829       &EmulateInstructionARM::EmulateSTRThumb,
13830       "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13831      {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13832       &EmulateInstructionARM::EmulateSTRThumb,
13833       "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13834      {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13835       &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13836      {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13837       &EmulateInstructionARM::EmulateSTRRegister,
13838       "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13839      {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13840       &EmulateInstructionARM::EmulateSTRBThumb,
13841       "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13842      {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13843       &EmulateInstructionARM::EmulateSTRBThumb,
13844       "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13845      {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13846       &EmulateInstructionARM::EmulateSTRBThumb,
13847       "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13848      {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13849       &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13850      {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13851       &EmulateInstructionARM::EmulateSTRHRegister,
13852       "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13853      {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13854       &EmulateInstructionARM::EmulateSTREX,
13855       "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13856      {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13857       &EmulateInstructionARM::EmulateSTRDImm,
13858       "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13859      {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13860       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13861      {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13862       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13863      {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13864       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13865      {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13866       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13867      {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13868       &EmulateInstructionARM::EmulateVST1Multiple,
13869       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13870      {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13871       &EmulateInstructionARM::EmulateVST1Single,
13872       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13873
13874      //----------------------------------------------------------------------
13875      // Other instructions
13876      //----------------------------------------------------------------------
13877      {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13878       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13879      {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13880       &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13881      {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13882       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13883      {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13884       &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13885      {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13886       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13887      {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13888       &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13889      {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13890       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13891      {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13892       &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13893  };
13894
13895  const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13896  for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13897    if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13898        (g_thumb_opcodes[i].variants & arm_isa) != 0)
13899      return &g_thumb_opcodes[i];
13900  }
13901  return NULL;
13902}
13903
13904bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13905  m_arch = arch;
13906  m_arm_isa = 0;
13907  const char *arch_cstr = arch.GetArchitectureName();
13908  if (arch_cstr) {
13909    if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13910      m_arm_isa = ARMv4T;
13911    else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13912      m_arm_isa = ARMv5TEJ;
13913    else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13914      m_arm_isa = ARMv5TE;
13915    else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13916      m_arm_isa = ARMv5T;
13917    else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13918      m_arm_isa = ARMv6K;
13919    else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13920      m_arm_isa = ARMv6T2;
13921    else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13922      m_arm_isa = ARMv7S;
13923    else if (0 == ::strcasecmp(arch_cstr, "arm"))
13924      m_arm_isa = ARMvAll;
13925    else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13926      m_arm_isa = ARMvAll;
13927    else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13928      m_arm_isa = ARMv4;
13929    else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13930      m_arm_isa = ARMv6;
13931    else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13932      m_arm_isa = ARMv7;
13933    else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13934      m_arm_isa = ARMv8;
13935  }
13936  return m_arm_isa != 0;
13937}
13938
13939bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13940                                           const Address &inst_addr,
13941                                           Target *target) {
13942  if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13943    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13944        m_arch.IsAlwaysThumbInstructions())
13945      m_opcode_mode = eModeThumb;
13946    else {
13947      AddressClass addr_class = inst_addr.GetAddressClass();
13948
13949      if ((addr_class == eAddressClassCode) ||
13950          (addr_class == eAddressClassUnknown))
13951        m_opcode_mode = eModeARM;
13952      else if (addr_class == eAddressClassCodeAlternateISA)
13953        m_opcode_mode = eModeThumb;
13954      else
13955        return false;
13956    }
13957    if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13958      m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13959    else
13960      m_opcode_cpsr = CPSR_MODE_USR;
13961    return true;
13962  }
13963  return false;
13964}
13965
13966bool EmulateInstructionARM::ReadInstruction() {
13967  bool success = false;
13968  m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13969                                       LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13970  if (success) {
13971    addr_t pc =
13972        ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13973                             LLDB_INVALID_ADDRESS, &success);
13974    if (success) {
13975      Context read_inst_context;
13976      read_inst_context.type = eContextReadOpcode;
13977      read_inst_context.SetNoArgs();
13978
13979      if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13980        m_opcode_mode = eModeThumb;
13981        uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13982
13983        if (success) {
13984          if ((thumb_opcode & 0xe000) != 0xe000 ||
13985              ((thumb_opcode & 0x1800u) == 0)) {
13986            m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13987          } else {
13988            m_opcode.SetOpcode32(
13989                (thumb_opcode << 16) |
13990                    MemARead(read_inst_context, pc + 2, 2, 0, &success),
13991                GetByteOrder());
13992          }
13993        }
13994      } else {
13995        m_opcode_mode = eModeARM;
13996        m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13997                             GetByteOrder());
13998      }
13999
14000      if (!m_ignore_conditions) {
14001        // If we are not ignoreing the conditions then init the it session from
14002        // the current
14003        // value of cpsr.
14004        uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
14005                      Bits32(m_opcode_cpsr, 26, 25);
14006        if (it != 0)
14007          m_it_session.InitIT(it);
14008      }
14009    }
14010  }
14011  if (!success) {
14012    m_opcode_mode = eModeInvalid;
14013    m_addr = LLDB_INVALID_ADDRESS;
14014  }
14015  return success;
14016}
14017
14018uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
14019
14020bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
14021  // If we are ignoring conditions, then always return true.
14022  // this allows us to iterate over disassembly code and still
14023  // emulate an instruction even if we don't have all the right
14024  // bits set in the CPSR register...
14025  if (m_ignore_conditions)
14026    return true;
14027
14028  const uint32_t cond = CurrentCond(opcode);
14029  if (cond == UINT32_MAX)
14030    return false;
14031
14032  bool result = false;
14033  switch (UnsignedBits(cond, 3, 1)) {
14034  case 0:
14035    if (m_opcode_cpsr == 0)
14036      result = true;
14037    else
14038      result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
14039    break;
14040  case 1:
14041    if (m_opcode_cpsr == 0)
14042      result = true;
14043    else
14044      result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
14045    break;
14046  case 2:
14047    if (m_opcode_cpsr == 0)
14048      result = true;
14049    else
14050      result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
14051    break;
14052  case 3:
14053    if (m_opcode_cpsr == 0)
14054      result = true;
14055    else
14056      result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
14057    break;
14058  case 4:
14059    if (m_opcode_cpsr == 0)
14060      result = true;
14061    else
14062      result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
14063               ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
14064    break;
14065  case 5:
14066    if (m_opcode_cpsr == 0)
14067      result = true;
14068    else {
14069      bool n = (m_opcode_cpsr & MASK_CPSR_N);
14070      bool v = (m_opcode_cpsr & MASK_CPSR_V);
14071      result = n == v;
14072    }
14073    break;
14074  case 6:
14075    if (m_opcode_cpsr == 0)
14076      result = true;
14077    else {
14078      bool n = (m_opcode_cpsr & MASK_CPSR_N);
14079      bool v = (m_opcode_cpsr & MASK_CPSR_V);
14080      result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
14081    }
14082    break;
14083  case 7:
14084    // Always execute (cond == 0b1110, or the special 0b1111 which gives
14085    // opcodes different meanings, but always means execution happens.
14086    return true;
14087  }
14088
14089  if (cond & 1)
14090    result = !result;
14091  return result;
14092}
14093
14094uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
14095  switch (m_opcode_mode) {
14096  case eModeInvalid:
14097    break;
14098
14099  case eModeARM:
14100    return UnsignedBits(opcode, 31, 28);
14101
14102  case eModeThumb:
14103    // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
14104    // 'cond' field of the encoding.
14105    {
14106      const uint32_t byte_size = m_opcode.GetByteSize();
14107      if (byte_size == 2) {
14108        if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
14109          return Bits32(opcode, 11, 8);
14110      } else if (byte_size == 4) {
14111        if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
14112            Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
14113          return Bits32(opcode, 25, 22);
14114        }
14115      } else
14116        // We have an invalid thumb instruction, let's bail out.
14117        break;
14118
14119      return m_it_session.GetCond();
14120    }
14121  }
14122  return UINT32_MAX; // Return invalid value
14123}
14124
14125bool EmulateInstructionARM::InITBlock() {
14126  return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
14127}
14128
14129bool EmulateInstructionARM::LastInITBlock() {
14130  return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
14131}
14132
14133bool EmulateInstructionARM::BadMode(uint32_t mode) {
14134
14135  switch (mode) {
14136  case 16:
14137    return false; // '10000'
14138  case 17:
14139    return false; // '10001'
14140  case 18:
14141    return false; // '10010'
14142  case 19:
14143    return false; // '10011'
14144  case 22:
14145    return false; // '10110'
14146  case 23:
14147    return false; // '10111'
14148  case 27:
14149    return false; // '11011'
14150  case 31:
14151    return false; // '11111'
14152  default:
14153    return true;
14154  }
14155  return true;
14156}
14157
14158bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14159  uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14160
14161  if (BadMode(mode))
14162    return false;
14163
14164  if (mode == 16)
14165    return false;
14166
14167  return true;
14168}
14169
14170void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14171                                             bool affect_execstate) {
14172  bool privileged = CurrentModeIsPrivileged();
14173
14174  uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14175
14176  if (BitIsSet(bytemask, 3)) {
14177    tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14178    if (affect_execstate)
14179      tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14180  }
14181
14182  if (BitIsSet(bytemask, 2)) {
14183    tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14184  }
14185
14186  if (BitIsSet(bytemask, 1)) {
14187    if (affect_execstate)
14188      tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14189    tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14190    if (privileged)
14191      tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14192  }
14193
14194  if (BitIsSet(bytemask, 0)) {
14195    if (privileged)
14196      tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14197    if (affect_execstate)
14198      tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14199    if (privileged)
14200      tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14201  }
14202
14203  m_opcode_cpsr = tmp_cpsr;
14204}
14205
14206bool EmulateInstructionARM::BranchWritePC(const Context &context,
14207                                          uint32_t addr) {
14208  addr_t target;
14209
14210  // Check the current instruction set.
14211  if (CurrentInstrSet() == eModeARM)
14212    target = addr & 0xfffffffc;
14213  else
14214    target = addr & 0xfffffffe;
14215
14216  if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14217                             LLDB_REGNUM_GENERIC_PC, target))
14218    return false;
14219
14220  return true;
14221}
14222
14223// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14224// inspecting addr.
14225bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14226  addr_t target;
14227  // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14228  // we want to record it and issue a WriteRegister callback so the clients
14229  // can track the mode changes accordingly.
14230  bool cpsr_changed = false;
14231
14232  if (BitIsSet(addr, 0)) {
14233    if (CurrentInstrSet() != eModeThumb) {
14234      SelectInstrSet(eModeThumb);
14235      cpsr_changed = true;
14236    }
14237    target = addr & 0xfffffffe;
14238    context.SetISA(eModeThumb);
14239  } else if (BitIsClear(addr, 1)) {
14240    if (CurrentInstrSet() != eModeARM) {
14241      SelectInstrSet(eModeARM);
14242      cpsr_changed = true;
14243    }
14244    target = addr & 0xfffffffc;
14245    context.SetISA(eModeARM);
14246  } else
14247    return false; // address<1:0> == '10' => UNPREDICTABLE
14248
14249  if (cpsr_changed) {
14250    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14251                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14252      return false;
14253  }
14254  if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14255                             LLDB_REGNUM_GENERIC_PC, target))
14256    return false;
14257
14258  return true;
14259}
14260
14261// Dispatches to either BXWritePC or BranchWritePC based on architecture
14262// versions.
14263bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14264  if (ArchVersion() >= ARMv5T)
14265    return BXWritePC(context, addr);
14266  else
14267    return BranchWritePC((const Context)context, addr);
14268}
14269
14270// Dispatches to either BXWritePC or BranchWritePC based on architecture
14271// versions and current instruction set.
14272bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14273  if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14274    return BXWritePC(context, addr);
14275  else
14276    return BranchWritePC((const Context)context, addr);
14277}
14278
14279EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14280  return m_opcode_mode;
14281}
14282
14283// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14284// ReadInstruction() is performed.  This function has a side effect of updating
14285// the m_new_inst_cpsr member variable if necessary.
14286bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14287  m_new_inst_cpsr = m_opcode_cpsr;
14288  switch (arm_or_thumb) {
14289  default:
14290    return false;
14291  case eModeARM:
14292    // Clear the T bit.
14293    m_new_inst_cpsr &= ~MASK_CPSR_T;
14294    break;
14295  case eModeThumb:
14296    // Set the T bit.
14297    m_new_inst_cpsr |= MASK_CPSR_T;
14298    break;
14299  }
14300  return true;
14301}
14302
14303// This function returns TRUE if the processor currently provides support for
14304// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14305// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
14306bool EmulateInstructionARM::UnalignedSupport() {
14307  return (ArchVersion() >= ARMv7);
14308}
14309
14310// The main addition and subtraction instructions can produce status information
14311// about both unsigned carry and signed overflow conditions.  This status
14312// information can be used to synthesize multi-word additions and subtractions.
14313EmulateInstructionARM::AddWithCarryResult
14314EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14315  uint32_t result;
14316  uint8_t carry_out;
14317  uint8_t overflow;
14318
14319  uint64_t unsigned_sum = x + y + carry_in;
14320  int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14321
14322  result = UnsignedBits(unsigned_sum, 31, 0);
14323  //    carry_out = (result == unsigned_sum ? 0 : 1);
14324  overflow = ((int32_t)result == signed_sum ? 0 : 1);
14325
14326  if (carry_in)
14327    carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14328  else
14329    carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14330
14331  AddWithCarryResult res = {result, carry_out, overflow};
14332  return res;
14333}
14334
14335uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14336  lldb::RegisterKind reg_kind;
14337  uint32_t reg_num;
14338  switch (num) {
14339  case SP_REG:
14340    reg_kind = eRegisterKindGeneric;
14341    reg_num = LLDB_REGNUM_GENERIC_SP;
14342    break;
14343  case LR_REG:
14344    reg_kind = eRegisterKindGeneric;
14345    reg_num = LLDB_REGNUM_GENERIC_RA;
14346    break;
14347  case PC_REG:
14348    reg_kind = eRegisterKindGeneric;
14349    reg_num = LLDB_REGNUM_GENERIC_PC;
14350    break;
14351  default:
14352    if (num < SP_REG) {
14353      reg_kind = eRegisterKindDWARF;
14354      reg_num = dwarf_r0 + num;
14355    } else {
14356      // assert(0 && "Invalid register number");
14357      *success = false;
14358      return UINT32_MAX;
14359    }
14360    break;
14361  }
14362
14363  // Read our register.
14364  uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14365
14366  // When executing an ARM instruction , PC reads as the address of the current
14367  // instruction plus 8.
14368  // When executing a Thumb instruction , PC reads as the address of the current
14369  // instruction plus 4.
14370  if (num == 15) {
14371    if (CurrentInstrSet() == eModeARM)
14372      val += 8;
14373    else
14374      val += 4;
14375  }
14376
14377  return val;
14378}
14379
14380// Write the result to the ARM core register Rd, and optionally update the
14381// condition flags based on the result.
14382//
14383// This helper method tries to encapsulate the following pseudocode from the
14384// ARM Architecture Reference Manual:
14385//
14386// if d == 15 then         // Can only occur for encoding A1
14387//     ALUWritePC(result); // setflags is always FALSE here
14388// else
14389//     R[d] = result;
14390//     if setflags then
14391//         APSR.N = result<31>;
14392//         APSR.Z = IsZeroBit(result);
14393//         APSR.C = carry;
14394//         // APSR.V unchanged
14395//
14396// In the above case, the API client does not pass in the overflow arg, which
14397// defaults to ~0u.
14398bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14399    Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14400    const uint32_t carry, const uint32_t overflow) {
14401  if (Rd == 15) {
14402    if (!ALUWritePC(context, result))
14403      return false;
14404  } else {
14405    lldb::RegisterKind reg_kind;
14406    uint32_t reg_num;
14407    switch (Rd) {
14408    case SP_REG:
14409      reg_kind = eRegisterKindGeneric;
14410      reg_num = LLDB_REGNUM_GENERIC_SP;
14411      break;
14412    case LR_REG:
14413      reg_kind = eRegisterKindGeneric;
14414      reg_num = LLDB_REGNUM_GENERIC_RA;
14415      break;
14416    default:
14417      reg_kind = eRegisterKindDWARF;
14418      reg_num = dwarf_r0 + Rd;
14419    }
14420    if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14421      return false;
14422    if (setflags)
14423      return WriteFlags(context, result, carry, overflow);
14424  }
14425  return true;
14426}
14427
14428// This helper method tries to encapsulate the following pseudocode from the
14429// ARM Architecture Reference Manual:
14430//
14431// APSR.N = result<31>;
14432// APSR.Z = IsZeroBit(result);
14433// APSR.C = carry;
14434// APSR.V = overflow
14435//
14436// Default arguments can be specified for carry and overflow parameters, which
14437// means
14438// not to update the respective flags.
14439bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14440                                       const uint32_t carry,
14441                                       const uint32_t overflow) {
14442  m_new_inst_cpsr = m_opcode_cpsr;
14443  SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14444  SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14445  if (carry != ~0u)
14446    SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14447  if (overflow != ~0u)
14448    SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14449  if (m_new_inst_cpsr != m_opcode_cpsr) {
14450    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14451                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14452      return false;
14453  }
14454  return true;
14455}
14456
14457bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14458  ARMOpcode *opcode_data = NULL;
14459
14460  if (m_opcode_mode == eModeThumb)
14461    opcode_data =
14462        GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14463  else if (m_opcode_mode == eModeARM)
14464    opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14465
14466  const bool auto_advance_pc =
14467      evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14468  m_ignore_conditions =
14469      evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14470
14471  bool success = false;
14472  if (m_opcode_cpsr == 0 || m_ignore_conditions == false) {
14473    m_opcode_cpsr =
14474        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14475  }
14476
14477  // Only return false if we are unable to read the CPSR if we care about
14478  // conditions
14479  if (success == false && m_ignore_conditions == false)
14480    return false;
14481
14482  uint32_t orig_pc_value = 0;
14483  if (auto_advance_pc) {
14484    orig_pc_value =
14485        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14486    if (!success)
14487      return false;
14488  }
14489
14490  // Call the Emulate... function if we managed to decode the opcode.
14491  if (opcode_data) {
14492    success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14493                                             opcode_data->encoding);
14494    if (!success)
14495      return false;
14496  }
14497
14498  // Advance the ITSTATE bits to their values for the next instruction if we
14499  // haven't just executed
14500  // an IT instruction what initialized it.
14501  if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14502      (opcode_data == nullptr ||
14503       opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14504    m_it_session.ITAdvance();
14505
14506  if (auto_advance_pc) {
14507    uint32_t after_pc_value =
14508        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14509    if (!success)
14510      return false;
14511
14512    if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
14513      after_pc_value += m_opcode.GetByteSize();
14514
14515      EmulateInstruction::Context context;
14516      context.type = eContextAdvancePC;
14517      context.SetNoArgs();
14518      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14519                                 after_pc_value))
14520        return false;
14521    }
14522  }
14523  return true;
14524}
14525
14526EmulateInstruction::InstructionCondition
14527EmulateInstructionARM::GetInstructionCondition() {
14528  const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14529  if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14530    return EmulateInstruction::UnconditionalCondition;
14531  return cond;
14532}
14533
14534bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14535                                          OptionValueDictionary *test_data) {
14536  if (!test_data) {
14537    out_stream->Printf("TestEmulation: Missing test data.\n");
14538    return false;
14539  }
14540
14541  static ConstString opcode_key("opcode");
14542  static ConstString before_key("before_state");
14543  static ConstString after_key("after_state");
14544
14545  OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14546
14547  uint32_t test_opcode;
14548  if ((value_sp.get() == NULL) ||
14549      (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14550    out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14551    return false;
14552  }
14553  test_opcode = value_sp->GetUInt64Value();
14554
14555  if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14556      arch.IsAlwaysThumbInstructions()) {
14557    m_opcode_mode = eModeThumb;
14558    if (test_opcode < 0x10000)
14559      m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14560    else
14561      m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14562  } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14563    m_opcode_mode = eModeARM;
14564    m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14565  } else {
14566    out_stream->Printf("TestEmulation:  Invalid arch.\n");
14567    return false;
14568  }
14569
14570  EmulationStateARM before_state;
14571  EmulationStateARM after_state;
14572
14573  value_sp = test_data->GetValueForKey(before_key);
14574  if ((value_sp.get() == NULL) ||
14575      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14576    out_stream->Printf("TestEmulation:  Failed to find 'before' state.\n");
14577    return false;
14578  }
14579
14580  OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14581  if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14582    out_stream->Printf("TestEmulation:  Failed loading 'before' state.\n");
14583    return false;
14584  }
14585
14586  value_sp = test_data->GetValueForKey(after_key);
14587  if ((value_sp.get() == NULL) ||
14588      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14589    out_stream->Printf("TestEmulation:  Failed to find 'after' state.\n");
14590    return false;
14591  }
14592
14593  state_dictionary = value_sp->GetAsDictionary();
14594  if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14595    out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14596    return false;
14597  }
14598
14599  SetBaton((void *)&before_state);
14600  SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14601               &EmulationStateARM::WritePseudoMemory,
14602               &EmulationStateARM::ReadPseudoRegister,
14603               &EmulationStateARM::WritePseudoRegister);
14604
14605  bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14606  if (!success) {
14607    out_stream->Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14608    return false;
14609  }
14610
14611  success = before_state.CompareState(after_state);
14612  if (!success)
14613    out_stream->Printf(
14614        "TestEmulation:  'before' and 'after' states do not match.\n");
14615
14616  return success;
14617}
14618//
14619//
14620// const char *
14621// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14622//{
14623//    if (reg_kind == eRegisterKindGeneric)
14624//    {
14625//        switch (reg_num)
14626//        {
14627//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14628//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14629//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14630//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14631//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14632//        default: return NULL;
14633//        }
14634//    }
14635//    else if (reg_kind == eRegisterKindDWARF)
14636//    {
14637//        return GetARMDWARFRegisterName (reg_num);
14638//    }
14639//    return NULL;
14640//}
14641//
14642bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14643  unwind_plan.Clear();
14644  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14645
14646  UnwindPlan::RowSP row(new UnwindPlan::Row);
14647
14648  // Our previous Call Frame Address is the stack pointer
14649  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14650
14651  unwind_plan.AppendRow(row);
14652  unwind_plan.SetSourceName("EmulateInstructionARM");
14653  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14654  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14655  unwind_plan.SetReturnAddressRegister(dwarf_lr);
14656  return true;
14657}
14658