EmulateInstructionARM.cpp revision 353358
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <stdlib.h>
10
11#include "EmulateInstructionARM.h"
12#include "EmulationStateARM.h"
13#include "lldb/Core/Address.h"
14#include "lldb/Core/PluginManager.h"
15#include "lldb/Host/PosixApi.h"
16#include "lldb/Interpreter/OptionValueArray.h"
17#include "lldb/Interpreter/OptionValueDictionary.h"
18#include "lldb/Symbol/UnwindPlan.h"
19#include "lldb/Utility/ArchSpec.h"
20#include "lldb/Utility/ConstString.h"
21#include "lldb/Utility/Stream.h"
22
23#include "Plugins/Process/Utility/ARMDefines.h"
24#include "Plugins/Process/Utility/ARMUtils.h"
25#include "Utility/ARM_DWARF_Registers.h"
26
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/Support/MathExtras.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33// Convenient macro definitions.
34#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36
37#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38
39//
40// ITSession implementation
41//
42
43static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo &reg_info) {
44  ::memset(&reg_info, 0, sizeof(RegisterInfo));
45  ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
46
47  if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) {
48    reg_info.byte_size = 16;
49    reg_info.format = eFormatVectorOfUInt8;
50    reg_info.encoding = eEncodingVector;
51  }
52
53  if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) {
54    reg_info.byte_size = 8;
55    reg_info.format = eFormatFloat;
56    reg_info.encoding = eEncodingIEEE754;
57  } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) {
58    reg_info.byte_size = 4;
59    reg_info.format = eFormatFloat;
60    reg_info.encoding = eEncodingIEEE754;
61  } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) {
62    reg_info.byte_size = 12;
63    reg_info.format = eFormatFloat;
64    reg_info.encoding = eEncodingIEEE754;
65  } else {
66    reg_info.byte_size = 4;
67    reg_info.format = eFormatHex;
68    reg_info.encoding = eEncodingUint;
69  }
70
71  reg_info.kinds[eRegisterKindDWARF] = reg_num;
72
73  switch (reg_num) {
74  case dwarf_r0:
75    reg_info.name = "r0";
76    break;
77  case dwarf_r1:
78    reg_info.name = "r1";
79    break;
80  case dwarf_r2:
81    reg_info.name = "r2";
82    break;
83  case dwarf_r3:
84    reg_info.name = "r3";
85    break;
86  case dwarf_r4:
87    reg_info.name = "r4";
88    break;
89  case dwarf_r5:
90    reg_info.name = "r5";
91    break;
92  case dwarf_r6:
93    reg_info.name = "r6";
94    break;
95  case dwarf_r7:
96    reg_info.name = "r7";
97    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
98    break;
99  case dwarf_r8:
100    reg_info.name = "r8";
101    break;
102  case dwarf_r9:
103    reg_info.name = "r9";
104    break;
105  case dwarf_r10:
106    reg_info.name = "r10";
107    break;
108  case dwarf_r11:
109    reg_info.name = "r11";
110    break;
111  case dwarf_r12:
112    reg_info.name = "r12";
113    break;
114  case dwarf_sp:
115    reg_info.name = "sp";
116    reg_info.alt_name = "r13";
117    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
118    break;
119  case dwarf_lr:
120    reg_info.name = "lr";
121    reg_info.alt_name = "r14";
122    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
123    break;
124  case dwarf_pc:
125    reg_info.name = "pc";
126    reg_info.alt_name = "r15";
127    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
128    break;
129  case dwarf_cpsr:
130    reg_info.name = "cpsr";
131    reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
132    break;
133
134  case dwarf_s0:
135    reg_info.name = "s0";
136    break;
137  case dwarf_s1:
138    reg_info.name = "s1";
139    break;
140  case dwarf_s2:
141    reg_info.name = "s2";
142    break;
143  case dwarf_s3:
144    reg_info.name = "s3";
145    break;
146  case dwarf_s4:
147    reg_info.name = "s4";
148    break;
149  case dwarf_s5:
150    reg_info.name = "s5";
151    break;
152  case dwarf_s6:
153    reg_info.name = "s6";
154    break;
155  case dwarf_s7:
156    reg_info.name = "s7";
157    break;
158  case dwarf_s8:
159    reg_info.name = "s8";
160    break;
161  case dwarf_s9:
162    reg_info.name = "s9";
163    break;
164  case dwarf_s10:
165    reg_info.name = "s10";
166    break;
167  case dwarf_s11:
168    reg_info.name = "s11";
169    break;
170  case dwarf_s12:
171    reg_info.name = "s12";
172    break;
173  case dwarf_s13:
174    reg_info.name = "s13";
175    break;
176  case dwarf_s14:
177    reg_info.name = "s14";
178    break;
179  case dwarf_s15:
180    reg_info.name = "s15";
181    break;
182  case dwarf_s16:
183    reg_info.name = "s16";
184    break;
185  case dwarf_s17:
186    reg_info.name = "s17";
187    break;
188  case dwarf_s18:
189    reg_info.name = "s18";
190    break;
191  case dwarf_s19:
192    reg_info.name = "s19";
193    break;
194  case dwarf_s20:
195    reg_info.name = "s20";
196    break;
197  case dwarf_s21:
198    reg_info.name = "s21";
199    break;
200  case dwarf_s22:
201    reg_info.name = "s22";
202    break;
203  case dwarf_s23:
204    reg_info.name = "s23";
205    break;
206  case dwarf_s24:
207    reg_info.name = "s24";
208    break;
209  case dwarf_s25:
210    reg_info.name = "s25";
211    break;
212  case dwarf_s26:
213    reg_info.name = "s26";
214    break;
215  case dwarf_s27:
216    reg_info.name = "s27";
217    break;
218  case dwarf_s28:
219    reg_info.name = "s28";
220    break;
221  case dwarf_s29:
222    reg_info.name = "s29";
223    break;
224  case dwarf_s30:
225    reg_info.name = "s30";
226    break;
227  case dwarf_s31:
228    reg_info.name = "s31";
229    break;
230
231  // FPA Registers 0-7
232  case dwarf_f0:
233    reg_info.name = "f0";
234    break;
235  case dwarf_f1:
236    reg_info.name = "f1";
237    break;
238  case dwarf_f2:
239    reg_info.name = "f2";
240    break;
241  case dwarf_f3:
242    reg_info.name = "f3";
243    break;
244  case dwarf_f4:
245    reg_info.name = "f4";
246    break;
247  case dwarf_f5:
248    reg_info.name = "f5";
249    break;
250  case dwarf_f6:
251    reg_info.name = "f6";
252    break;
253  case dwarf_f7:
254    reg_info.name = "f7";
255    break;
256
257  // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
258  // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
259  case dwarf_wCGR0:
260    reg_info.name = "wCGR0/ACC0";
261    break;
262  case dwarf_wCGR1:
263    reg_info.name = "wCGR1/ACC1";
264    break;
265  case dwarf_wCGR2:
266    reg_info.name = "wCGR2/ACC2";
267    break;
268  case dwarf_wCGR3:
269    reg_info.name = "wCGR3/ACC3";
270    break;
271  case dwarf_wCGR4:
272    reg_info.name = "wCGR4/ACC4";
273    break;
274  case dwarf_wCGR5:
275    reg_info.name = "wCGR5/ACC5";
276    break;
277  case dwarf_wCGR6:
278    reg_info.name = "wCGR6/ACC6";
279    break;
280  case dwarf_wCGR7:
281    reg_info.name = "wCGR7/ACC7";
282    break;
283
284  // Intel wireless MMX data registers 0 - 15
285  case dwarf_wR0:
286    reg_info.name = "wR0";
287    break;
288  case dwarf_wR1:
289    reg_info.name = "wR1";
290    break;
291  case dwarf_wR2:
292    reg_info.name = "wR2";
293    break;
294  case dwarf_wR3:
295    reg_info.name = "wR3";
296    break;
297  case dwarf_wR4:
298    reg_info.name = "wR4";
299    break;
300  case dwarf_wR5:
301    reg_info.name = "wR5";
302    break;
303  case dwarf_wR6:
304    reg_info.name = "wR6";
305    break;
306  case dwarf_wR7:
307    reg_info.name = "wR7";
308    break;
309  case dwarf_wR8:
310    reg_info.name = "wR8";
311    break;
312  case dwarf_wR9:
313    reg_info.name = "wR9";
314    break;
315  case dwarf_wR10:
316    reg_info.name = "wR10";
317    break;
318  case dwarf_wR11:
319    reg_info.name = "wR11";
320    break;
321  case dwarf_wR12:
322    reg_info.name = "wR12";
323    break;
324  case dwarf_wR13:
325    reg_info.name = "wR13";
326    break;
327  case dwarf_wR14:
328    reg_info.name = "wR14";
329    break;
330  case dwarf_wR15:
331    reg_info.name = "wR15";
332    break;
333
334  case dwarf_spsr:
335    reg_info.name = "spsr";
336    break;
337  case dwarf_spsr_fiq:
338    reg_info.name = "spsr_fiq";
339    break;
340  case dwarf_spsr_irq:
341    reg_info.name = "spsr_irq";
342    break;
343  case dwarf_spsr_abt:
344    reg_info.name = "spsr_abt";
345    break;
346  case dwarf_spsr_und:
347    reg_info.name = "spsr_und";
348    break;
349  case dwarf_spsr_svc:
350    reg_info.name = "spsr_svc";
351    break;
352
353  case dwarf_r8_usr:
354    reg_info.name = "r8_usr";
355    break;
356  case dwarf_r9_usr:
357    reg_info.name = "r9_usr";
358    break;
359  case dwarf_r10_usr:
360    reg_info.name = "r10_usr";
361    break;
362  case dwarf_r11_usr:
363    reg_info.name = "r11_usr";
364    break;
365  case dwarf_r12_usr:
366    reg_info.name = "r12_usr";
367    break;
368  case dwarf_r13_usr:
369    reg_info.name = "r13_usr";
370    break;
371  case dwarf_r14_usr:
372    reg_info.name = "r14_usr";
373    break;
374  case dwarf_r8_fiq:
375    reg_info.name = "r8_fiq";
376    break;
377  case dwarf_r9_fiq:
378    reg_info.name = "r9_fiq";
379    break;
380  case dwarf_r10_fiq:
381    reg_info.name = "r10_fiq";
382    break;
383  case dwarf_r11_fiq:
384    reg_info.name = "r11_fiq";
385    break;
386  case dwarf_r12_fiq:
387    reg_info.name = "r12_fiq";
388    break;
389  case dwarf_r13_fiq:
390    reg_info.name = "r13_fiq";
391    break;
392  case dwarf_r14_fiq:
393    reg_info.name = "r14_fiq";
394    break;
395  case dwarf_r13_irq:
396    reg_info.name = "r13_irq";
397    break;
398  case dwarf_r14_irq:
399    reg_info.name = "r14_irq";
400    break;
401  case dwarf_r13_abt:
402    reg_info.name = "r13_abt";
403    break;
404  case dwarf_r14_abt:
405    reg_info.name = "r14_abt";
406    break;
407  case dwarf_r13_und:
408    reg_info.name = "r13_und";
409    break;
410  case dwarf_r14_und:
411    reg_info.name = "r14_und";
412    break;
413  case dwarf_r13_svc:
414    reg_info.name = "r13_svc";
415    break;
416  case dwarf_r14_svc:
417    reg_info.name = "r14_svc";
418    break;
419
420  // Intel wireless MMX control register in co-processor 0 - 7
421  case dwarf_wC0:
422    reg_info.name = "wC0";
423    break;
424  case dwarf_wC1:
425    reg_info.name = "wC1";
426    break;
427  case dwarf_wC2:
428    reg_info.name = "wC2";
429    break;
430  case dwarf_wC3:
431    reg_info.name = "wC3";
432    break;
433  case dwarf_wC4:
434    reg_info.name = "wC4";
435    break;
436  case dwarf_wC5:
437    reg_info.name = "wC5";
438    break;
439  case dwarf_wC6:
440    reg_info.name = "wC6";
441    break;
442  case dwarf_wC7:
443    reg_info.name = "wC7";
444    break;
445
446  // VFP-v3/Neon
447  case dwarf_d0:
448    reg_info.name = "d0";
449    break;
450  case dwarf_d1:
451    reg_info.name = "d1";
452    break;
453  case dwarf_d2:
454    reg_info.name = "d2";
455    break;
456  case dwarf_d3:
457    reg_info.name = "d3";
458    break;
459  case dwarf_d4:
460    reg_info.name = "d4";
461    break;
462  case dwarf_d5:
463    reg_info.name = "d5";
464    break;
465  case dwarf_d6:
466    reg_info.name = "d6";
467    break;
468  case dwarf_d7:
469    reg_info.name = "d7";
470    break;
471  case dwarf_d8:
472    reg_info.name = "d8";
473    break;
474  case dwarf_d9:
475    reg_info.name = "d9";
476    break;
477  case dwarf_d10:
478    reg_info.name = "d10";
479    break;
480  case dwarf_d11:
481    reg_info.name = "d11";
482    break;
483  case dwarf_d12:
484    reg_info.name = "d12";
485    break;
486  case dwarf_d13:
487    reg_info.name = "d13";
488    break;
489  case dwarf_d14:
490    reg_info.name = "d14";
491    break;
492  case dwarf_d15:
493    reg_info.name = "d15";
494    break;
495  case dwarf_d16:
496    reg_info.name = "d16";
497    break;
498  case dwarf_d17:
499    reg_info.name = "d17";
500    break;
501  case dwarf_d18:
502    reg_info.name = "d18";
503    break;
504  case dwarf_d19:
505    reg_info.name = "d19";
506    break;
507  case dwarf_d20:
508    reg_info.name = "d20";
509    break;
510  case dwarf_d21:
511    reg_info.name = "d21";
512    break;
513  case dwarf_d22:
514    reg_info.name = "d22";
515    break;
516  case dwarf_d23:
517    reg_info.name = "d23";
518    break;
519  case dwarf_d24:
520    reg_info.name = "d24";
521    break;
522  case dwarf_d25:
523    reg_info.name = "d25";
524    break;
525  case dwarf_d26:
526    reg_info.name = "d26";
527    break;
528  case dwarf_d27:
529    reg_info.name = "d27";
530    break;
531  case dwarf_d28:
532    reg_info.name = "d28";
533    break;
534  case dwarf_d29:
535    reg_info.name = "d29";
536    break;
537  case dwarf_d30:
538    reg_info.name = "d30";
539    break;
540  case dwarf_d31:
541    reg_info.name = "d31";
542    break;
543
544  // NEON 128-bit vector registers (overlays the d registers)
545  case dwarf_q0:
546    reg_info.name = "q0";
547    break;
548  case dwarf_q1:
549    reg_info.name = "q1";
550    break;
551  case dwarf_q2:
552    reg_info.name = "q2";
553    break;
554  case dwarf_q3:
555    reg_info.name = "q3";
556    break;
557  case dwarf_q4:
558    reg_info.name = "q4";
559    break;
560  case dwarf_q5:
561    reg_info.name = "q5";
562    break;
563  case dwarf_q6:
564    reg_info.name = "q6";
565    break;
566  case dwarf_q7:
567    reg_info.name = "q7";
568    break;
569  case dwarf_q8:
570    reg_info.name = "q8";
571    break;
572  case dwarf_q9:
573    reg_info.name = "q9";
574    break;
575  case dwarf_q10:
576    reg_info.name = "q10";
577    break;
578  case dwarf_q11:
579    reg_info.name = "q11";
580    break;
581  case dwarf_q12:
582    reg_info.name = "q12";
583    break;
584  case dwarf_q13:
585    reg_info.name = "q13";
586    break;
587  case dwarf_q14:
588    reg_info.name = "q14";
589    break;
590  case dwarf_q15:
591    reg_info.name = "q15";
592    break;
593
594  default:
595    return false;
596  }
597  return true;
598}
599
600// A8.6.50
601// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
602static uint32_t CountITSize(uint32_t ITMask) {
603  // First count the trailing zeros of the IT mask.
604  uint32_t TZ = llvm::countTrailingZeros(ITMask);
605  if (TZ > 3) {
606#ifdef LLDB_CONFIGURATION_DEBUG
607    printf("Encoding error: IT Mask '0000'\n");
608#endif
609    return 0;
610  }
611  return (4 - TZ);
612}
613
614// Init ITState.  Note that at least one bit is always 1 in mask.
615bool ITSession::InitIT(uint32_t bits7_0) {
616  ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
617  if (ITCounter == 0)
618    return false;
619
620  // A8.6.50 IT
621  unsigned short FirstCond = Bits32(bits7_0, 7, 4);
622  if (FirstCond == 0xF) {
623#ifdef LLDB_CONFIGURATION_DEBUG
624    printf("Encoding error: IT FirstCond '1111'\n");
625#endif
626    return false;
627  }
628  if (FirstCond == 0xE && ITCounter != 1) {
629#ifdef LLDB_CONFIGURATION_DEBUG
630    printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
631#endif
632    return false;
633  }
634
635  ITState = bits7_0;
636  return true;
637}
638
639// Update ITState if necessary.
640void ITSession::ITAdvance() {
641  // assert(ITCounter);
642  --ITCounter;
643  if (ITCounter == 0)
644    ITState = 0;
645  else {
646    unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
647    SetBits32(ITState, 4, 0, NewITState4_0);
648  }
649}
650
651// Return true if we're inside an IT Block.
652bool ITSession::InITBlock() { return ITCounter != 0; }
653
654// Return true if we're the last instruction inside an IT Block.
655bool ITSession::LastInITBlock() { return ITCounter == 1; }
656
657// Get condition bits for the current thumb instruction.
658uint32_t ITSession::GetCond() {
659  if (InITBlock())
660    return Bits32(ITState, 7, 4);
661  else
662    return COND_AL;
663}
664
665// ARM constants used during decoding
666#define REG_RD 0
667#define LDM_REGLIST 1
668#define SP_REG 13
669#define LR_REG 14
670#define PC_REG 15
671#define PC_REGLIST_BIT 0x8000
672
673#define ARMv4 (1u << 0)
674#define ARMv4T (1u << 1)
675#define ARMv5T (1u << 2)
676#define ARMv5TE (1u << 3)
677#define ARMv5TEJ (1u << 4)
678#define ARMv6 (1u << 5)
679#define ARMv6K (1u << 6)
680#define ARMv6T2 (1u << 7)
681#define ARMv7 (1u << 8)
682#define ARMv7S (1u << 9)
683#define ARMv8 (1u << 10)
684#define ARMvAll (0xffffffffu)
685
686#define ARMV4T_ABOVE                                                           \
687  (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 |   \
688   ARMv7S | ARMv8)
689#define ARMV5_ABOVE                                                            \
690  (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S |   \
691   ARMv8)
692#define ARMV5TE_ABOVE                                                          \
693  (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
694#define ARMV5J_ABOVE                                                           \
695  (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
696#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
697#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
698#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
699
700#define No_VFP 0
701#define VFPv1 (1u << 1)
702#define VFPv2 (1u << 2)
703#define VFPv3 (1u << 3)
704#define AdvancedSIMD (1u << 4)
705
706#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
707#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
708#define VFPv2v3 (VFPv2 | VFPv3)
709
710//
711// EmulateInstructionARM implementation
712//
713
714void EmulateInstructionARM::Initialize() {
715  PluginManager::RegisterPlugin(GetPluginNameStatic(),
716                                GetPluginDescriptionStatic(), CreateInstance);
717}
718
719void EmulateInstructionARM::Terminate() {
720  PluginManager::UnregisterPlugin(CreateInstance);
721}
722
723ConstString EmulateInstructionARM::GetPluginNameStatic() {
724  static ConstString g_name("arm");
725  return g_name;
726}
727
728const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
729  return "Emulate instructions for the ARM architecture.";
730}
731
732EmulateInstruction *
733EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
734                                      InstructionType inst_type) {
735  if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
736          inst_type)) {
737    if (arch.GetTriple().getArch() == llvm::Triple::arm) {
738      std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
739          new EmulateInstructionARM(arch));
740
741      if (emulate_insn_up)
742        return emulate_insn_up.release();
743    } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
744      std::unique_ptr<EmulateInstructionARM> emulate_insn_up(
745          new EmulateInstructionARM(arch));
746
747      if (emulate_insn_up)
748        return emulate_insn_up.release();
749    }
750  }
751
752  return nullptr;
753}
754
755bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
756  if (arch.GetTriple().getArch() == llvm::Triple::arm)
757    return true;
758  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
759    return true;
760
761  return false;
762}
763
764// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for
765// many ARM instructions.
766bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
767  EmulateInstruction::Context context;
768  context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
769  context.SetNoArgs();
770
771  uint32_t random_data = rand();
772  const uint32_t addr_byte_size = GetAddressByteSize();
773
774  return MemAWrite(context, address, random_data, addr_byte_size);
775}
776
777// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM
778// instructions.
779bool EmulateInstructionARM::WriteBits32Unknown(int n) {
780  EmulateInstruction::Context context;
781  context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
782  context.SetNoArgs();
783
784  bool success;
785  uint32_t data =
786      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
787
788  if (!success)
789    return false;
790
791  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
792    return false;
793
794  return true;
795}
796
797bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
798                                            uint32_t reg_num,
799                                            RegisterInfo &reg_info) {
800  if (reg_kind == eRegisterKindGeneric) {
801    switch (reg_num) {
802    case LLDB_REGNUM_GENERIC_PC:
803      reg_kind = eRegisterKindDWARF;
804      reg_num = dwarf_pc;
805      break;
806    case LLDB_REGNUM_GENERIC_SP:
807      reg_kind = eRegisterKindDWARF;
808      reg_num = dwarf_sp;
809      break;
810    case LLDB_REGNUM_GENERIC_FP:
811      reg_kind = eRegisterKindDWARF;
812      reg_num = dwarf_r7;
813      break;
814    case LLDB_REGNUM_GENERIC_RA:
815      reg_kind = eRegisterKindDWARF;
816      reg_num = dwarf_lr;
817      break;
818    case LLDB_REGNUM_GENERIC_FLAGS:
819      reg_kind = eRegisterKindDWARF;
820      reg_num = dwarf_cpsr;
821      break;
822    default:
823      return false;
824    }
825  }
826
827  if (reg_kind == eRegisterKindDWARF)
828    return GetARMDWARFRegisterInfo(reg_num, reg_info);
829  return false;
830}
831
832uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
833  if (m_arch.GetTriple().isAndroid())
834    return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
835  bool is_apple = false;
836  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
837    is_apple = true;
838  switch (m_arch.GetTriple().getOS()) {
839  case llvm::Triple::Darwin:
840  case llvm::Triple::MacOSX:
841  case llvm::Triple::IOS:
842  case llvm::Triple::TvOS:
843  case llvm::Triple::WatchOS:
844  // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
845    is_apple = true;
846    break;
847  default:
848    break;
849  }
850
851  /* On Apple iOS et al, the frame pointer register is always r7.
852   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
853   */
854
855  uint32_t fp_regnum = 11;
856
857  if (is_apple)
858    fp_regnum = 7;
859
860  if (m_opcode_mode == eModeThumb)
861    fp_regnum = 7;
862
863  return fp_regnum;
864}
865
866uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
867  bool is_apple = false;
868  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
869    is_apple = true;
870  switch (m_arch.GetTriple().getOS()) {
871  case llvm::Triple::Darwin:
872  case llvm::Triple::MacOSX:
873  case llvm::Triple::IOS:
874    is_apple = true;
875    break;
876  default:
877    break;
878  }
879
880  /* On Apple iOS et al, the frame pointer register is always r7.
881   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
882   */
883
884  uint32_t fp_regnum = dwarf_r11;
885
886  if (is_apple)
887    fp_regnum = dwarf_r7;
888
889  if (m_opcode_mode == eModeThumb)
890    fp_regnum = dwarf_r7;
891
892  return fp_regnum;
893}
894
895// Push Multiple Registers stores multiple registers to the stack, storing to
896// consecutive memory locations ending just below the address in SP, and
897// updates
898// SP to point to the start of the stored data.
899bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
900                                        const ARMEncoding encoding) {
901#if 0
902    // ARM pseudo code...
903    if (ConditionPassed())
904    {
905        EncodingSpecificOperations();
906        NullCheckIfThumbEE(13);
907        address = SP - 4*BitCount(registers);
908
909        for (i = 0 to 14)
910        {
911            if (registers<i> == '1')
912            {
913                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
914                    MemA[address,4] = bits(32) UNKNOWN;
915                else
916                    MemA[address,4] = R[i];
917                address = address + 4;
918            }
919        }
920
921        if (registers<15> == '1') // Only possible for encoding A1 or A2
922            MemA[address,4] = PCStoreValue();
923
924        SP = SP - 4*BitCount(registers);
925    }
926#endif
927
928  bool success = false;
929  if (ConditionPassed(opcode)) {
930    const uint32_t addr_byte_size = GetAddressByteSize();
931    const addr_t sp = ReadCoreReg(SP_REG, &success);
932    if (!success)
933      return false;
934    uint32_t registers = 0;
935    uint32_t Rt; // the source register
936    switch (encoding) {
937    case eEncodingT1:
938      registers = Bits32(opcode, 7, 0);
939      // The M bit represents LR.
940      if (Bit32(opcode, 8))
941        registers |= (1u << 14);
942      // if BitCount(registers) < 1 then UNPREDICTABLE;
943      if (BitCount(registers) < 1)
944        return false;
945      break;
946    case eEncodingT2:
947      // Ignore bits 15 & 13.
948      registers = Bits32(opcode, 15, 0) & ~0xa000;
949      // if BitCount(registers) < 2 then UNPREDICTABLE;
950      if (BitCount(registers) < 2)
951        return false;
952      break;
953    case eEncodingT3:
954      Rt = Bits32(opcode, 15, 12);
955      // if BadReg(t) then UNPREDICTABLE;
956      if (BadReg(Rt))
957        return false;
958      registers = (1u << Rt);
959      break;
960    case eEncodingA1:
961      registers = Bits32(opcode, 15, 0);
962      // Instead of return false, let's handle the following case as well,
963      // which amounts to pushing one reg onto the full descending stacks.
964      // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
965      break;
966    case eEncodingA2:
967      Rt = Bits32(opcode, 15, 12);
968      // if t == 13 then UNPREDICTABLE;
969      if (Rt == dwarf_sp)
970        return false;
971      registers = (1u << Rt);
972      break;
973    default:
974      return false;
975    }
976    addr_t sp_offset = addr_byte_size * BitCount(registers);
977    addr_t addr = sp - sp_offset;
978    uint32_t i;
979
980    EmulateInstruction::Context context;
981    context.type = EmulateInstruction::eContextPushRegisterOnStack;
982    RegisterInfo reg_info;
983    RegisterInfo sp_reg;
984    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
985    for (i = 0; i < 15; ++i) {
986      if (BitIsSet(registers, i)) {
987        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
988        context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
989        uint32_t reg_value = ReadCoreReg(i, &success);
990        if (!success)
991          return false;
992        if (!MemAWrite(context, addr, reg_value, addr_byte_size))
993          return false;
994        addr += addr_byte_size;
995      }
996    }
997
998    if (BitIsSet(registers, 15)) {
999      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
1000      context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
1001      const uint32_t pc = ReadCoreReg(PC_REG, &success);
1002      if (!success)
1003        return false;
1004      if (!MemAWrite(context, addr, pc, addr_byte_size))
1005        return false;
1006    }
1007
1008    context.type = EmulateInstruction::eContextAdjustStackPointer;
1009    context.SetImmediateSigned(-sp_offset);
1010
1011    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1012                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1013      return false;
1014  }
1015  return true;
1016}
1017
1018// Pop Multiple Registers loads multiple registers from the stack, loading from
1019// consecutive memory locations staring at the address in SP, and updates
1020// SP to point just above the loaded data.
1021bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
1022                                       const ARMEncoding encoding) {
1023#if 0
1024    // ARM pseudo code...
1025    if (ConditionPassed())
1026    {
1027        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
1028        address = SP;
1029        for i = 0 to 14
1030            if registers<i> == '1' then
1031                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
1032        if registers<15> == '1' then
1033            if UnalignedAllowed then
1034                LoadWritePC(MemU[address,4]);
1035            else
1036                LoadWritePC(MemA[address,4]);
1037        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
1038        if registers<13> == '1' then SP = bits(32) UNKNOWN;
1039    }
1040#endif
1041
1042  bool success = false;
1043
1044  if (ConditionPassed(opcode)) {
1045    const uint32_t addr_byte_size = GetAddressByteSize();
1046    const addr_t sp = ReadCoreReg(SP_REG, &success);
1047    if (!success)
1048      return false;
1049    uint32_t registers = 0;
1050    uint32_t Rt; // the destination register
1051    switch (encoding) {
1052    case eEncodingT1:
1053      registers = Bits32(opcode, 7, 0);
1054      // The P bit represents PC.
1055      if (Bit32(opcode, 8))
1056        registers |= (1u << 15);
1057      // if BitCount(registers) < 1 then UNPREDICTABLE;
1058      if (BitCount(registers) < 1)
1059        return false;
1060      break;
1061    case eEncodingT2:
1062      // Ignore bit 13.
1063      registers = Bits32(opcode, 15, 0) & ~0x2000;
1064      // if BitCount(registers) < 2 || (P == '1' && M == '1') then
1065      // UNPREDICTABLE;
1066      if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
1067        return false;
1068      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
1069      // UNPREDICTABLE;
1070      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
1071        return false;
1072      break;
1073    case eEncodingT3:
1074      Rt = Bits32(opcode, 15, 12);
1075      // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
1076      // UNPREDICTABLE;
1077      if (Rt == 13)
1078        return false;
1079      if (Rt == 15 && InITBlock() && !LastInITBlock())
1080        return false;
1081      registers = (1u << Rt);
1082      break;
1083    case eEncodingA1:
1084      registers = Bits32(opcode, 15, 0);
1085      // Instead of return false, let's handle the following case as well,
1086      // which amounts to popping one reg from the full descending stacks.
1087      // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
1088
1089      // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
1090      if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
1091        return false;
1092      break;
1093    case eEncodingA2:
1094      Rt = Bits32(opcode, 15, 12);
1095      // if t == 13 then UNPREDICTABLE;
1096      if (Rt == dwarf_sp)
1097        return false;
1098      registers = (1u << Rt);
1099      break;
1100    default:
1101      return false;
1102    }
1103    addr_t sp_offset = addr_byte_size * BitCount(registers);
1104    addr_t addr = sp;
1105    uint32_t i, data;
1106
1107    EmulateInstruction::Context context;
1108    context.type = EmulateInstruction::eContextPopRegisterOffStack;
1109
1110    RegisterInfo sp_reg;
1111    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1112
1113    for (i = 0; i < 15; ++i) {
1114      if (BitIsSet(registers, i)) {
1115        context.SetAddress(addr);
1116        data = MemARead(context, addr, 4, 0, &success);
1117        if (!success)
1118          return false;
1119        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
1120                                   data))
1121          return false;
1122        addr += addr_byte_size;
1123      }
1124    }
1125
1126    if (BitIsSet(registers, 15)) {
1127      context.SetRegisterPlusOffset(sp_reg, addr - sp);
1128      data = MemARead(context, addr, 4, 0, &success);
1129      if (!success)
1130        return false;
1131      // In ARMv5T and above, this is an interworking branch.
1132      if (!LoadWritePC(context, data))
1133        return false;
1134      // addr += addr_byte_size;
1135    }
1136
1137    context.type = EmulateInstruction::eContextAdjustStackPointer;
1138    context.SetImmediateSigned(sp_offset);
1139
1140    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1141                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1142      return false;
1143  }
1144  return true;
1145}
1146
1147// Set r7 or ip to point to saved value residing within the stack.
1148// ADD (SP plus immediate)
1149bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
1150                                              const ARMEncoding encoding) {
1151#if 0
1152    // ARM pseudo code...
1153    if (ConditionPassed())
1154    {
1155        EncodingSpecificOperations();
1156        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1157        if d == 15 then
1158           ALUWritePC(result); // setflags is always FALSE here
1159        else
1160            R[d] = result;
1161            if setflags then
1162                APSR.N = result<31>;
1163                APSR.Z = IsZeroBit(result);
1164                APSR.C = carry;
1165                APSR.V = overflow;
1166    }
1167#endif
1168
1169  bool success = false;
1170
1171  if (ConditionPassed(opcode)) {
1172    const addr_t sp = ReadCoreReg(SP_REG, &success);
1173    if (!success)
1174      return false;
1175    uint32_t Rd; // the destination register
1176    uint32_t imm32;
1177    switch (encoding) {
1178    case eEncodingT1:
1179      Rd = 7;
1180      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
1181      break;
1182    case eEncodingA1:
1183      Rd = Bits32(opcode, 15, 12);
1184      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1185      break;
1186    default:
1187      return false;
1188    }
1189    addr_t sp_offset = imm32;
1190    addr_t addr = sp + sp_offset; // a pointer to the stack area
1191
1192    EmulateInstruction::Context context;
1193    if (Rd == GetFramePointerRegisterNumber())
1194      context.type = eContextSetFramePointer;
1195    else
1196      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1197    RegisterInfo sp_reg;
1198    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1199    context.SetRegisterPlusOffset(sp_reg, sp_offset);
1200
1201    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
1202                               addr))
1203      return false;
1204  }
1205  return true;
1206}
1207
1208// Set r7 or ip to the current stack pointer.
1209// MOV (register)
1210bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
1211                                           const ARMEncoding encoding) {
1212#if 0
1213    // ARM pseudo code...
1214    if (ConditionPassed())
1215    {
1216        EncodingSpecificOperations();
1217        result = R[m];
1218        if d == 15 then
1219            ALUWritePC(result); // setflags is always FALSE here
1220        else
1221            R[d] = result;
1222            if setflags then
1223                APSR.N = result<31>;
1224                APSR.Z = IsZeroBit(result);
1225                // APSR.C unchanged
1226                // APSR.V unchanged
1227    }
1228#endif
1229
1230  bool success = false;
1231
1232  if (ConditionPassed(opcode)) {
1233    const addr_t sp = ReadCoreReg(SP_REG, &success);
1234    if (!success)
1235      return false;
1236    uint32_t Rd; // the destination register
1237    switch (encoding) {
1238    case eEncodingT1:
1239      Rd = 7;
1240      break;
1241    case eEncodingA1:
1242      Rd = 12;
1243      break;
1244    default:
1245      return false;
1246    }
1247
1248    EmulateInstruction::Context context;
1249    if (Rd == GetFramePointerRegisterNumber())
1250      context.type = EmulateInstruction::eContextSetFramePointer;
1251    else
1252      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1253    RegisterInfo sp_reg;
1254    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1255    context.SetRegisterPlusOffset(sp_reg, 0);
1256
1257    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
1258      return false;
1259  }
1260  return true;
1261}
1262
1263// Move from high register (r8-r15) to low register (r0-r7).
1264// MOV (register)
1265bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
1266                                              const ARMEncoding encoding) {
1267  return EmulateMOVRdRm(opcode, encoding);
1268}
1269
1270// Move from register to register.
1271// MOV (register)
1272bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
1273                                           const ARMEncoding encoding) {
1274#if 0
1275    // ARM pseudo code...
1276    if (ConditionPassed())
1277    {
1278        EncodingSpecificOperations();
1279        result = R[m];
1280        if d == 15 then
1281            ALUWritePC(result); // setflags is always FALSE here
1282        else
1283            R[d] = result;
1284            if setflags then
1285                APSR.N = result<31>;
1286                APSR.Z = IsZeroBit(result);
1287                // APSR.C unchanged
1288                // APSR.V unchanged
1289    }
1290#endif
1291
1292  bool success = false;
1293
1294  if (ConditionPassed(opcode)) {
1295    uint32_t Rm; // the source register
1296    uint32_t Rd; // the destination register
1297    bool setflags;
1298    switch (encoding) {
1299    case eEncodingT1:
1300      Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1301      Rm = Bits32(opcode, 6, 3);
1302      setflags = false;
1303      if (Rd == 15 && InITBlock() && !LastInITBlock())
1304        return false;
1305      break;
1306    case eEncodingT2:
1307      Rd = Bits32(opcode, 2, 0);
1308      Rm = Bits32(opcode, 5, 3);
1309      setflags = true;
1310      if (InITBlock())
1311        return false;
1312      break;
1313    case eEncodingT3:
1314      Rd = Bits32(opcode, 11, 8);
1315      Rm = Bits32(opcode, 3, 0);
1316      setflags = BitIsSet(opcode, 20);
1317      // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1318      if (setflags && (BadReg(Rd) || BadReg(Rm)))
1319        return false;
1320      // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
1321      // UNPREDICTABLE;
1322      if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
1323        return false;
1324      break;
1325    case eEncodingA1:
1326      Rd = Bits32(opcode, 15, 12);
1327      Rm = Bits32(opcode, 3, 0);
1328      setflags = BitIsSet(opcode, 20);
1329
1330      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1331      // instructions;
1332      if (Rd == 15 && setflags)
1333        return EmulateSUBSPcLrEtc(opcode, encoding);
1334      break;
1335    default:
1336      return false;
1337    }
1338    uint32_t result = ReadCoreReg(Rm, &success);
1339    if (!success)
1340      return false;
1341
1342    // The context specifies that Rm is to be moved into Rd.
1343    EmulateInstruction::Context context;
1344    if (Rd == 13)
1345      context.type = EmulateInstruction::eContextAdjustStackPointer;
1346    else
1347      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1348    RegisterInfo dwarf_reg;
1349    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1350    context.SetRegisterPlusOffset(dwarf_reg, 0);
1351
1352    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
1353      return false;
1354  }
1355  return true;
1356}
1357
1358// Move (immediate) writes an immediate value to the destination register.  It
1359// can optionally update the condition flags based on the value.
1360// MOV (immediate)
1361bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
1362                                            const ARMEncoding encoding) {
1363#if 0
1364    // ARM pseudo code...
1365    if (ConditionPassed())
1366    {
1367        EncodingSpecificOperations();
1368        result = imm32;
1369        if d == 15 then         // Can only occur for ARM encoding
1370            ALUWritePC(result); // setflags is always FALSE here
1371        else
1372            R[d] = result;
1373            if setflags then
1374                APSR.N = result<31>;
1375                APSR.Z = IsZeroBit(result);
1376                APSR.C = carry;
1377                // APSR.V unchanged
1378    }
1379#endif
1380
1381  if (ConditionPassed(opcode)) {
1382    uint32_t Rd;    // the destination register
1383    uint32_t imm32; // the immediate value to be written to Rd
1384    uint32_t carry =
1385        0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
1386           // for setflags == false, this value is a don't care initialized to
1387           // 0 to silence the static analyzer
1388    bool setflags;
1389    switch (encoding) {
1390    case eEncodingT1:
1391      Rd = Bits32(opcode, 10, 8);
1392      setflags = !InITBlock();
1393      imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
1394      carry = APSR_C;
1395
1396      break;
1397
1398    case eEncodingT2:
1399      Rd = Bits32(opcode, 11, 8);
1400      setflags = BitIsSet(opcode, 20);
1401      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1402      if (BadReg(Rd))
1403        return false;
1404
1405      break;
1406
1407    case eEncodingT3: {
1408      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
1409      // 32);
1410      Rd = Bits32(opcode, 11, 8);
1411      setflags = false;
1412      uint32_t imm4 = Bits32(opcode, 19, 16);
1413      uint32_t imm3 = Bits32(opcode, 14, 12);
1414      uint32_t i = Bit32(opcode, 26);
1415      uint32_t imm8 = Bits32(opcode, 7, 0);
1416      imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
1417
1418      // if BadReg(d) then UNPREDICTABLE;
1419      if (BadReg(Rd))
1420        return false;
1421    } break;
1422
1423    case eEncodingA1:
1424      // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
1425      // ARMExpandImm_C(imm12, APSR.C);
1426      Rd = Bits32(opcode, 15, 12);
1427      setflags = BitIsSet(opcode, 20);
1428      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1429
1430      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1431      // instructions;
1432      if ((Rd == 15) && setflags)
1433        return EmulateSUBSPcLrEtc(opcode, encoding);
1434
1435      break;
1436
1437    case eEncodingA2: {
1438      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
1439      Rd = Bits32(opcode, 15, 12);
1440      setflags = false;
1441      uint32_t imm4 = Bits32(opcode, 19, 16);
1442      uint32_t imm12 = Bits32(opcode, 11, 0);
1443      imm32 = (imm4 << 12) | imm12;
1444
1445      // if d == 15 then UNPREDICTABLE;
1446      if (Rd == 15)
1447        return false;
1448    } break;
1449
1450    default:
1451      return false;
1452    }
1453    uint32_t result = imm32;
1454
1455    // The context specifies that an immediate is to be moved into Rd.
1456    EmulateInstruction::Context context;
1457    context.type = EmulateInstruction::eContextImmediate;
1458    context.SetNoArgs();
1459
1460    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1461      return false;
1462  }
1463  return true;
1464}
1465
1466// MUL multiplies two register values.  The least significant 32 bits of the
1467// result are written to the destination
1468// register.  These 32 bits do not depend on whether the source register values
1469// are considered to be signed values or unsigned values.
1470//
1471// Optionally, it can update the condition flags based on the result.  In the
1472// Thumb instruction set, this option is limited to only a few forms of the
1473// instruction.
1474bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
1475                                       const ARMEncoding encoding) {
1476#if 0
1477    if ConditionPassed() then
1478        EncodingSpecificOperations();
1479        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1480        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1481        result = operand1 * operand2;
1482        R[d] = result<31:0>;
1483        if setflags then
1484            APSR.N = result<31>;
1485            APSR.Z = IsZeroBit(result);
1486            if ArchVersion() == 4 then
1487                APSR.C = bit UNKNOWN;
1488            // else APSR.C unchanged
1489            // APSR.V always unchanged
1490#endif
1491
1492  if (ConditionPassed(opcode)) {
1493    uint32_t d;
1494    uint32_t n;
1495    uint32_t m;
1496    bool setflags;
1497
1498    // EncodingSpecificOperations();
1499    switch (encoding) {
1500    case eEncodingT1:
1501      // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
1502      d = Bits32(opcode, 2, 0);
1503      n = Bits32(opcode, 5, 3);
1504      m = Bits32(opcode, 2, 0);
1505      setflags = !InITBlock();
1506
1507      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1508      if ((ArchVersion() < ARMv6) && (d == n))
1509        return false;
1510
1511      break;
1512
1513    case eEncodingT2:
1514      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
1515      d = Bits32(opcode, 11, 8);
1516      n = Bits32(opcode, 19, 16);
1517      m = Bits32(opcode, 3, 0);
1518      setflags = false;
1519
1520      // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1521      if (BadReg(d) || BadReg(n) || BadReg(m))
1522        return false;
1523
1524      break;
1525
1526    case eEncodingA1:
1527      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1528      d = Bits32(opcode, 19, 16);
1529      n = Bits32(opcode, 3, 0);
1530      m = Bits32(opcode, 11, 8);
1531      setflags = BitIsSet(opcode, 20);
1532
1533      // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1534      if ((d == 15) || (n == 15) || (m == 15))
1535        return false;
1536
1537      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1538      if ((ArchVersion() < ARMv6) && (d == n))
1539        return false;
1540
1541      break;
1542
1543    default:
1544      return false;
1545    }
1546
1547    bool success = false;
1548
1549    // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1550    // results
1551    uint64_t operand1 =
1552        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1553    if (!success)
1554      return false;
1555
1556    // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1557    // results
1558    uint64_t operand2 =
1559        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1560    if (!success)
1561      return false;
1562
1563    // result = operand1 * operand2;
1564    uint64_t result = operand1 * operand2;
1565
1566    // R[d] = result<31:0>;
1567    RegisterInfo op1_reg;
1568    RegisterInfo op2_reg;
1569    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1570    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1571
1572    EmulateInstruction::Context context;
1573    context.type = eContextArithmetic;
1574    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1575
1576    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1577                               (0x0000ffff & result)))
1578      return false;
1579
1580    // if setflags then
1581    if (setflags) {
1582      // APSR.N = result<31>;
1583      // APSR.Z = IsZeroBit(result);
1584      m_new_inst_cpsr = m_opcode_cpsr;
1585      SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1586      SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1587      if (m_new_inst_cpsr != m_opcode_cpsr) {
1588        if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1589                                   LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1590          return false;
1591      }
1592
1593      // if ArchVersion() == 4 then
1594      // APSR.C = bit UNKNOWN;
1595    }
1596  }
1597  return true;
1598}
1599
1600// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1601// the destination register. It can optionally update the condition flags based
1602// on the value.
1603bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1604                                          const ARMEncoding encoding) {
1605#if 0
1606    // ARM pseudo code...
1607    if (ConditionPassed())
1608    {
1609        EncodingSpecificOperations();
1610        result = NOT(imm32);
1611        if d == 15 then         // Can only occur for ARM encoding
1612            ALUWritePC(result); // setflags is always FALSE here
1613        else
1614            R[d] = result;
1615            if setflags then
1616                APSR.N = result<31>;
1617                APSR.Z = IsZeroBit(result);
1618                APSR.C = carry;
1619                // APSR.V unchanged
1620    }
1621#endif
1622
1623  if (ConditionPassed(opcode)) {
1624    uint32_t Rd;    // the destination register
1625    uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1626    uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1627    bool setflags;
1628    switch (encoding) {
1629    case eEncodingT1:
1630      Rd = Bits32(opcode, 11, 8);
1631      setflags = BitIsSet(opcode, 20);
1632      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1633      break;
1634    case eEncodingA1:
1635      Rd = Bits32(opcode, 15, 12);
1636      setflags = BitIsSet(opcode, 20);
1637      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1638
1639      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1640      // instructions;
1641      if (Rd == 15 && setflags)
1642        return EmulateSUBSPcLrEtc(opcode, encoding);
1643      break;
1644    default:
1645      return false;
1646    }
1647    uint32_t result = ~imm32;
1648
1649    // The context specifies that an immediate is to be moved into Rd.
1650    EmulateInstruction::Context context;
1651    context.type = EmulateInstruction::eContextImmediate;
1652    context.SetNoArgs();
1653
1654    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1655      return false;
1656  }
1657  return true;
1658}
1659
1660// Bitwise NOT (register) writes the bitwise inverse of a register value to the
1661// destination register. It can optionally update the condition flags based on
1662// the result.
1663bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1664                                          const ARMEncoding encoding) {
1665#if 0
1666    // ARM pseudo code...
1667    if (ConditionPassed())
1668    {
1669        EncodingSpecificOperations();
1670        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1671        result = NOT(shifted);
1672        if d == 15 then         // Can only occur for ARM encoding
1673            ALUWritePC(result); // setflags is always FALSE here
1674        else
1675            R[d] = result;
1676            if setflags then
1677                APSR.N = result<31>;
1678                APSR.Z = IsZeroBit(result);
1679                APSR.C = carry;
1680                // APSR.V unchanged
1681    }
1682#endif
1683
1684  if (ConditionPassed(opcode)) {
1685    uint32_t Rm; // the source register
1686    uint32_t Rd; // the destination register
1687    ARM_ShifterType shift_t;
1688    uint32_t shift_n; // the shift applied to the value read from Rm
1689    bool setflags;
1690    uint32_t carry; // the carry bit after the shift operation
1691    switch (encoding) {
1692    case eEncodingT1:
1693      Rd = Bits32(opcode, 2, 0);
1694      Rm = Bits32(opcode, 5, 3);
1695      setflags = !InITBlock();
1696      shift_t = SRType_LSL;
1697      shift_n = 0;
1698      if (InITBlock())
1699        return false;
1700      break;
1701    case eEncodingT2:
1702      Rd = Bits32(opcode, 11, 8);
1703      Rm = Bits32(opcode, 3, 0);
1704      setflags = BitIsSet(opcode, 20);
1705      shift_n = DecodeImmShiftThumb(opcode, shift_t);
1706      // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1707      if (BadReg(Rd) || BadReg(Rm))
1708        return false;
1709      break;
1710    case eEncodingA1:
1711      Rd = Bits32(opcode, 15, 12);
1712      Rm = Bits32(opcode, 3, 0);
1713      setflags = BitIsSet(opcode, 20);
1714      shift_n = DecodeImmShiftARM(opcode, shift_t);
1715      break;
1716    default:
1717      return false;
1718    }
1719    bool success = false;
1720    uint32_t value = ReadCoreReg(Rm, &success);
1721    if (!success)
1722      return false;
1723
1724    uint32_t shifted =
1725        Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1726    if (!success)
1727      return false;
1728    uint32_t result = ~shifted;
1729
1730    // The context specifies that an immediate is to be moved into Rd.
1731    EmulateInstruction::Context context;
1732    context.type = EmulateInstruction::eContextImmediate;
1733    context.SetNoArgs();
1734
1735    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1736      return false;
1737  }
1738  return true;
1739}
1740
1741// PC relative immediate load into register, possibly followed by ADD (SP plus
1742// register).
1743// LDR (literal)
1744bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1745                                                   const ARMEncoding encoding) {
1746#if 0
1747    // ARM pseudo code...
1748    if (ConditionPassed())
1749    {
1750        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1751        base = Align(PC,4);
1752        address = if add then (base + imm32) else (base - imm32);
1753        data = MemU[address,4];
1754        if t == 15 then
1755            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1756        elsif UnalignedSupport() || address<1:0> = '00' then
1757            R[t] = data;
1758        else // Can only apply before ARMv7
1759            if CurrentInstrSet() == InstrSet_ARM then
1760                R[t] = ROR(data, 8*UInt(address<1:0>));
1761            else
1762                R[t] = bits(32) UNKNOWN;
1763    }
1764#endif
1765
1766  if (ConditionPassed(opcode)) {
1767    bool success = false;
1768    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1769    if (!success)
1770      return false;
1771
1772    // PC relative immediate load context
1773    EmulateInstruction::Context context;
1774    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1775    RegisterInfo pc_reg;
1776    GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1777    context.SetRegisterPlusOffset(pc_reg, 0);
1778
1779    uint32_t Rt;    // the destination register
1780    uint32_t imm32; // immediate offset from the PC
1781    bool add;       // +imm32 or -imm32?
1782    addr_t base;    // the base address
1783    addr_t address; // the PC relative address
1784    uint32_t data;  // the literal data value from the PC relative load
1785    switch (encoding) {
1786    case eEncodingT1:
1787      Rt = Bits32(opcode, 10, 8);
1788      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1789      add = true;
1790      break;
1791    case eEncodingT2:
1792      Rt = Bits32(opcode, 15, 12);
1793      imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1794      add = BitIsSet(opcode, 23);
1795      if (Rt == 15 && InITBlock() && !LastInITBlock())
1796        return false;
1797      break;
1798    default:
1799      return false;
1800    }
1801
1802    base = Align(pc, 4);
1803    if (add)
1804      address = base + imm32;
1805    else
1806      address = base - imm32;
1807
1808    context.SetRegisterPlusOffset(pc_reg, address - base);
1809    data = MemURead(context, address, 4, 0, &success);
1810    if (!success)
1811      return false;
1812
1813    if (Rt == 15) {
1814      if (Bits32(address, 1, 0) == 0) {
1815        // In ARMv5T and above, this is an interworking branch.
1816        if (!LoadWritePC(context, data))
1817          return false;
1818      } else
1819        return false;
1820    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1821      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1822                                 data))
1823        return false;
1824    } else // We don't handle ARM for now.
1825      return false;
1826  }
1827  return true;
1828}
1829
1830// An add operation to adjust the SP.
1831// ADD (SP plus immediate)
1832bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1833                                            const ARMEncoding encoding) {
1834#if 0
1835    // ARM pseudo code...
1836    if (ConditionPassed())
1837    {
1838        EncodingSpecificOperations();
1839        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1840        if d == 15 then // Can only occur for ARM encoding
1841            ALUWritePC(result); // setflags is always FALSE here
1842        else
1843            R[d] = result;
1844            if setflags then
1845                APSR.N = result<31>;
1846                APSR.Z = IsZeroBit(result);
1847                APSR.C = carry;
1848                APSR.V = overflow;
1849    }
1850#endif
1851
1852  bool success = false;
1853
1854  if (ConditionPassed(opcode)) {
1855    const addr_t sp = ReadCoreReg(SP_REG, &success);
1856    if (!success)
1857      return false;
1858    uint32_t imm32; // the immediate operand
1859    uint32_t d;
1860    bool setflags;
1861    switch (encoding) {
1862    case eEncodingT1:
1863      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1864      d = Bits32(opcode, 10, 8);
1865      imm32 = (Bits32(opcode, 7, 0) << 2);
1866      setflags = false;
1867      break;
1868
1869    case eEncodingT2:
1870      // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1871      d = 13;
1872      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1873      setflags = false;
1874      break;
1875
1876    case eEncodingT3:
1877      // d = UInt(Rd); setflags = (S == "1"); imm32 =
1878      // ThumbExpandImm(i:imm3:imm8);
1879      d = Bits32(opcode, 11, 8);
1880      imm32 = ThumbExpandImm(opcode);
1881      setflags = Bit32(opcode, 20);
1882
1883      // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1884      if (d == 15 && setflags == 1)
1885        return false; // CMN (immediate) not yet supported
1886
1887      // if d == 15 && S == "0" then UNPREDICTABLE;
1888      if (d == 15 && setflags == 0)
1889        return false;
1890      break;
1891
1892    case eEncodingT4: {
1893      // if Rn == '1111' then SEE ADR;
1894      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1895      d = Bits32(opcode, 11, 8);
1896      setflags = false;
1897      uint32_t i = Bit32(opcode, 26);
1898      uint32_t imm3 = Bits32(opcode, 14, 12);
1899      uint32_t imm8 = Bits32(opcode, 7, 0);
1900      imm32 = (i << 11) | (imm3 << 8) | imm8;
1901
1902      // if d == 15 then UNPREDICTABLE;
1903      if (d == 15)
1904        return false;
1905    } break;
1906
1907    default:
1908      return false;
1909    }
1910    // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1911    AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1912
1913    EmulateInstruction::Context context;
1914    if (d == 13)
1915      context.type = EmulateInstruction::eContextAdjustStackPointer;
1916    else
1917      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1918
1919    RegisterInfo sp_reg;
1920    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1921    context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1922
1923    if (d == 15) {
1924      if (!ALUWritePC(context, res.result))
1925        return false;
1926    } else {
1927      // R[d] = result;
1928      // if setflags then
1929      //     APSR.N = result<31>;
1930      //     APSR.Z = IsZeroBit(result);
1931      //     APSR.C = carry;
1932      //     APSR.V = overflow;
1933      if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1934                                     res.carry_out, res.overflow))
1935        return false;
1936    }
1937  }
1938  return true;
1939}
1940
1941// An add operation to adjust the SP.
1942// ADD (SP plus register)
1943bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1944                                           const ARMEncoding encoding) {
1945#if 0
1946    // ARM pseudo code...
1947    if (ConditionPassed())
1948    {
1949        EncodingSpecificOperations();
1950        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1951        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1952        if d == 15 then
1953            ALUWritePC(result); // setflags is always FALSE here
1954        else
1955            R[d] = result;
1956            if setflags then
1957                APSR.N = result<31>;
1958                APSR.Z = IsZeroBit(result);
1959                APSR.C = carry;
1960                APSR.V = overflow;
1961    }
1962#endif
1963
1964  bool success = false;
1965
1966  if (ConditionPassed(opcode)) {
1967    const addr_t sp = ReadCoreReg(SP_REG, &success);
1968    if (!success)
1969      return false;
1970    uint32_t Rm; // the second operand
1971    switch (encoding) {
1972    case eEncodingT2:
1973      Rm = Bits32(opcode, 6, 3);
1974      break;
1975    default:
1976      return false;
1977    }
1978    int32_t reg_value = ReadCoreReg(Rm, &success);
1979    if (!success)
1980      return false;
1981
1982    addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1983
1984    EmulateInstruction::Context context;
1985    context.type = eContextArithmetic;
1986    RegisterInfo sp_reg;
1987    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1988
1989    RegisterInfo other_reg;
1990    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1991    context.SetRegisterRegisterOperands(sp_reg, other_reg);
1992
1993    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1994                               LLDB_REGNUM_GENERIC_SP, addr))
1995      return false;
1996  }
1997  return true;
1998}
1999
2000// Branch with Link and Exchange Instruction Sets (immediate) calls a
2001// subroutine at a PC-relative address, and changes instruction set from ARM to
2002// Thumb, or from Thumb to ARM.
2003// BLX (immediate)
2004bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
2005                                                const ARMEncoding encoding) {
2006#if 0
2007    // ARM pseudo code...
2008    if (ConditionPassed())
2009    {
2010        EncodingSpecificOperations();
2011        if CurrentInstrSet() == InstrSet_ARM then
2012            LR = PC - 4;
2013        else
2014            LR = PC<31:1> : '1';
2015        if targetInstrSet == InstrSet_ARM then
2016            targetAddress = Align(PC,4) + imm32;
2017        else
2018            targetAddress = PC + imm32;
2019        SelectInstrSet(targetInstrSet);
2020        BranchWritePC(targetAddress);
2021    }
2022#endif
2023
2024  bool success = true;
2025
2026  if (ConditionPassed(opcode)) {
2027    EmulateInstruction::Context context;
2028    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2029    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2030    if (!success)
2031      return false;
2032    addr_t lr;     // next instruction address
2033    addr_t target; // target address
2034    int32_t imm32; // PC-relative offset
2035    switch (encoding) {
2036    case eEncodingT1: {
2037      lr = pc | 1u; // return address
2038      uint32_t S = Bit32(opcode, 26);
2039      uint32_t imm10 = Bits32(opcode, 25, 16);
2040      uint32_t J1 = Bit32(opcode, 13);
2041      uint32_t J2 = Bit32(opcode, 11);
2042      uint32_t imm11 = Bits32(opcode, 10, 0);
2043      uint32_t I1 = !(J1 ^ S);
2044      uint32_t I2 = !(J2 ^ S);
2045      uint32_t imm25 =
2046          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2047      imm32 = llvm::SignExtend32<25>(imm25);
2048      target = pc + imm32;
2049      SelectInstrSet(eModeThumb);
2050      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2051      if (InITBlock() && !LastInITBlock())
2052        return false;
2053      break;
2054    }
2055    case eEncodingT2: {
2056      lr = pc | 1u; // return address
2057      uint32_t S = Bit32(opcode, 26);
2058      uint32_t imm10H = Bits32(opcode, 25, 16);
2059      uint32_t J1 = Bit32(opcode, 13);
2060      uint32_t J2 = Bit32(opcode, 11);
2061      uint32_t imm10L = Bits32(opcode, 10, 1);
2062      uint32_t I1 = !(J1 ^ S);
2063      uint32_t I2 = !(J2 ^ S);
2064      uint32_t imm25 =
2065          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
2066      imm32 = llvm::SignExtend32<25>(imm25);
2067      target = Align(pc, 4) + imm32;
2068      SelectInstrSet(eModeARM);
2069      context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
2070      if (InITBlock() && !LastInITBlock())
2071        return false;
2072      break;
2073    }
2074    case eEncodingA1:
2075      lr = pc - 4; // return address
2076      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2077      target = Align(pc, 4) + imm32;
2078      SelectInstrSet(eModeARM);
2079      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2080      break;
2081    case eEncodingA2:
2082      lr = pc - 4; // return address
2083      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
2084                                     Bits32(opcode, 24, 24) << 1);
2085      target = pc + imm32;
2086      SelectInstrSet(eModeThumb);
2087      context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
2088      break;
2089    default:
2090      return false;
2091    }
2092    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2093                               LLDB_REGNUM_GENERIC_RA, lr))
2094      return false;
2095    if (!BranchWritePC(context, target))
2096      return false;
2097    if (m_opcode_cpsr != m_new_inst_cpsr)
2098      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2099                                 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2100        return false;
2101  }
2102  return true;
2103}
2104
2105// Branch with Link and Exchange (register) calls a subroutine at an address
2106// and instruction set specified by a register.
2107// BLX (register)
2108bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
2109                                         const ARMEncoding encoding) {
2110#if 0
2111    // ARM pseudo code...
2112    if (ConditionPassed())
2113    {
2114        EncodingSpecificOperations();
2115        target = R[m];
2116        if CurrentInstrSet() == InstrSet_ARM then
2117            next_instr_addr = PC - 4;
2118            LR = next_instr_addr;
2119        else
2120            next_instr_addr = PC - 2;
2121            LR = next_instr_addr<31:1> : '1';
2122        BXWritePC(target);
2123    }
2124#endif
2125
2126  bool success = false;
2127
2128  if (ConditionPassed(opcode)) {
2129    EmulateInstruction::Context context;
2130    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2131    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2132    addr_t lr; // next instruction address
2133    if (!success)
2134      return false;
2135    uint32_t Rm; // the register with the target address
2136    switch (encoding) {
2137    case eEncodingT1:
2138      lr = (pc - 2) | 1u; // return address
2139      Rm = Bits32(opcode, 6, 3);
2140      // if m == 15 then UNPREDICTABLE;
2141      if (Rm == 15)
2142        return false;
2143      if (InITBlock() && !LastInITBlock())
2144        return false;
2145      break;
2146    case eEncodingA1:
2147      lr = pc - 4; // return address
2148      Rm = Bits32(opcode, 3, 0);
2149      // if m == 15 then UNPREDICTABLE;
2150      if (Rm == 15)
2151        return false;
2152      break;
2153    default:
2154      return false;
2155    }
2156    addr_t target = ReadCoreReg(Rm, &success);
2157    if (!success)
2158      return false;
2159    RegisterInfo dwarf_reg;
2160    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2161    context.SetRegister(dwarf_reg);
2162    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2163                               LLDB_REGNUM_GENERIC_RA, lr))
2164      return false;
2165    if (!BXWritePC(context, target))
2166      return false;
2167  }
2168  return true;
2169}
2170
2171// Branch and Exchange causes a branch to an address and instruction set
2172// specified by a register.
2173bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
2174                                        const ARMEncoding encoding) {
2175#if 0
2176    // ARM pseudo code...
2177    if (ConditionPassed())
2178    {
2179        EncodingSpecificOperations();
2180        BXWritePC(R[m]);
2181    }
2182#endif
2183
2184  if (ConditionPassed(opcode)) {
2185    EmulateInstruction::Context context;
2186    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2187    uint32_t Rm; // the register with the target address
2188    switch (encoding) {
2189    case eEncodingT1:
2190      Rm = Bits32(opcode, 6, 3);
2191      if (InITBlock() && !LastInITBlock())
2192        return false;
2193      break;
2194    case eEncodingA1:
2195      Rm = Bits32(opcode, 3, 0);
2196      break;
2197    default:
2198      return false;
2199    }
2200    bool success = false;
2201    addr_t target = ReadCoreReg(Rm, &success);
2202    if (!success)
2203      return false;
2204
2205    RegisterInfo dwarf_reg;
2206    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2207    context.SetRegister(dwarf_reg);
2208    if (!BXWritePC(context, target))
2209      return false;
2210  }
2211  return true;
2212}
2213
2214// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
2215// attempt fails, it branches to an address and instruction set specified by a
2216// register as though it were a BX instruction.
2217//
2218// TODO: Emulate Jazelle architecture?
2219//       We currently assume that switching to Jazelle state fails, thus
2220//       treating BXJ as a BX operation.
2221bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
2222                                         const ARMEncoding encoding) {
2223#if 0
2224    // ARM pseudo code...
2225    if (ConditionPassed())
2226    {
2227        EncodingSpecificOperations();
2228        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
2229            BXWritePC(R[m]);
2230        else
2231            if JazelleAcceptsExecution() then
2232                SwitchToJazelleExecution();
2233            else
2234                SUBARCHITECTURE_DEFINED handler call;
2235    }
2236#endif
2237
2238  if (ConditionPassed(opcode)) {
2239    EmulateInstruction::Context context;
2240    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
2241    uint32_t Rm; // the register with the target address
2242    switch (encoding) {
2243    case eEncodingT1:
2244      Rm = Bits32(opcode, 19, 16);
2245      if (BadReg(Rm))
2246        return false;
2247      if (InITBlock() && !LastInITBlock())
2248        return false;
2249      break;
2250    case eEncodingA1:
2251      Rm = Bits32(opcode, 3, 0);
2252      if (Rm == 15)
2253        return false;
2254      break;
2255    default:
2256      return false;
2257    }
2258    bool success = false;
2259    addr_t target = ReadCoreReg(Rm, &success);
2260    if (!success)
2261      return false;
2262
2263    RegisterInfo dwarf_reg;
2264    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
2265    context.SetRegister(dwarf_reg);
2266    if (!BXWritePC(context, target))
2267      return false;
2268  }
2269  return true;
2270}
2271
2272// Set r7 to point to some ip offset.
2273// SUB (immediate)
2274bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
2275                                              const ARMEncoding encoding) {
2276#if 0
2277    // ARM pseudo code...
2278    if (ConditionPassed())
2279    {
2280        EncodingSpecificOperations();
2281        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2282        if d == 15 then // Can only occur for ARM encoding
2283           ALUWritePC(result); // setflags is always FALSE here
2284        else
2285            R[d] = result;
2286            if setflags then
2287                APSR.N = result<31>;
2288                APSR.Z = IsZeroBit(result);
2289                APSR.C = carry;
2290                APSR.V = overflow;
2291    }
2292#endif
2293
2294  if (ConditionPassed(opcode)) {
2295    bool success = false;
2296    const addr_t ip = ReadCoreReg(12, &success);
2297    if (!success)
2298      return false;
2299    uint32_t imm32;
2300    switch (encoding) {
2301    case eEncodingA1:
2302      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2303      break;
2304    default:
2305      return false;
2306    }
2307    addr_t ip_offset = imm32;
2308    addr_t addr = ip - ip_offset; // the adjusted ip value
2309
2310    EmulateInstruction::Context context;
2311    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2312    RegisterInfo dwarf_reg;
2313    GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
2314    context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
2315
2316    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
2317      return false;
2318  }
2319  return true;
2320}
2321
2322// Set ip to point to some stack offset.
2323// SUB (SP minus immediate)
2324bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
2325                                              const ARMEncoding encoding) {
2326#if 0
2327    // ARM pseudo code...
2328    if (ConditionPassed())
2329    {
2330        EncodingSpecificOperations();
2331        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2332        if d == 15 then // Can only occur for ARM encoding
2333           ALUWritePC(result); // setflags is always FALSE here
2334        else
2335            R[d] = result;
2336            if setflags then
2337                APSR.N = result<31>;
2338                APSR.Z = IsZeroBit(result);
2339                APSR.C = carry;
2340                APSR.V = overflow;
2341    }
2342#endif
2343
2344  if (ConditionPassed(opcode)) {
2345    bool success = false;
2346    const addr_t sp = ReadCoreReg(SP_REG, &success);
2347    if (!success)
2348      return false;
2349    uint32_t imm32;
2350    switch (encoding) {
2351    case eEncodingA1:
2352      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2353      break;
2354    default:
2355      return false;
2356    }
2357    addr_t sp_offset = imm32;
2358    addr_t addr = sp - sp_offset; // the adjusted stack pointer value
2359
2360    EmulateInstruction::Context context;
2361    context.type = EmulateInstruction::eContextRegisterPlusOffset;
2362    RegisterInfo dwarf_reg;
2363    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
2364    context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
2365
2366    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
2367      return false;
2368  }
2369  return true;
2370}
2371
2372// This instruction subtracts an immediate value from the SP value, and writes
2373// the result to the destination register.
2374//
2375// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
2376// storage.
2377bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
2378                                            const ARMEncoding encoding) {
2379#if 0
2380    // ARM pseudo code...
2381    if (ConditionPassed())
2382    {
2383        EncodingSpecificOperations();
2384        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
2385        if d == 15 then        // Can only occur for ARM encoding
2386           ALUWritePC(result); // setflags is always FALSE here
2387        else
2388            R[d] = result;
2389            if setflags then
2390                APSR.N = result<31>;
2391                APSR.Z = IsZeroBit(result);
2392                APSR.C = carry;
2393                APSR.V = overflow;
2394    }
2395#endif
2396
2397  bool success = false;
2398  if (ConditionPassed(opcode)) {
2399    const addr_t sp = ReadCoreReg(SP_REG, &success);
2400    if (!success)
2401      return false;
2402
2403    uint32_t Rd;
2404    bool setflags;
2405    uint32_t imm32;
2406    switch (encoding) {
2407    case eEncodingT1:
2408      Rd = 13;
2409      setflags = false;
2410      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
2411      break;
2412    case eEncodingT2:
2413      Rd = Bits32(opcode, 11, 8);
2414      setflags = BitIsSet(opcode, 20);
2415      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2416      if (Rd == 15 && setflags)
2417        return EmulateCMPImm(opcode, eEncodingT2);
2418      if (Rd == 15 && !setflags)
2419        return false;
2420      break;
2421    case eEncodingT3:
2422      Rd = Bits32(opcode, 11, 8);
2423      setflags = false;
2424      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
2425      if (Rd == 15)
2426        return false;
2427      break;
2428    case eEncodingA1:
2429      Rd = Bits32(opcode, 15, 12);
2430      setflags = BitIsSet(opcode, 20);
2431      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2432
2433      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
2434      // instructions;
2435      if (Rd == 15 && setflags)
2436        return EmulateSUBSPcLrEtc(opcode, encoding);
2437      break;
2438    default:
2439      return false;
2440    }
2441    AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
2442
2443    EmulateInstruction::Context context;
2444    if (Rd == 13) {
2445      uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
2446                              // to negate it, or the wrong
2447      // value gets passed down to context.SetImmediateSigned.
2448      context.type = EmulateInstruction::eContextAdjustStackPointer;
2449      context.SetImmediateSigned(-imm64); // the stack pointer offset
2450    } else {
2451      context.type = EmulateInstruction::eContextImmediate;
2452      context.SetNoArgs();
2453    }
2454
2455    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2456                                   res.carry_out, res.overflow))
2457      return false;
2458  }
2459  return true;
2460}
2461
2462// A store operation to the stack that also updates the SP.
2463bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
2464                                           const ARMEncoding encoding) {
2465#if 0
2466    // ARM pseudo code...
2467    if (ConditionPassed())
2468    {
2469        EncodingSpecificOperations();
2470        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2471        address = if index then offset_addr else R[n];
2472        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
2473        if wback then R[n] = offset_addr;
2474    }
2475#endif
2476
2477  bool success = false;
2478  if (ConditionPassed(opcode)) {
2479    const uint32_t addr_byte_size = GetAddressByteSize();
2480    const addr_t sp = ReadCoreReg(SP_REG, &success);
2481    if (!success)
2482      return false;
2483    uint32_t Rt; // the source register
2484    uint32_t imm12;
2485    uint32_t
2486        Rn; // This function assumes Rn is the SP, but we should verify that.
2487
2488    bool index;
2489    bool add;
2490    bool wback;
2491    switch (encoding) {
2492    case eEncodingA1:
2493      Rt = Bits32(opcode, 15, 12);
2494      imm12 = Bits32(opcode, 11, 0);
2495      Rn = Bits32(opcode, 19, 16);
2496
2497      if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
2498        return false;
2499
2500      index = BitIsSet(opcode, 24);
2501      add = BitIsSet(opcode, 23);
2502      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
2503
2504      if (wback && ((Rn == 15) || (Rn == Rt)))
2505        return false;
2506      break;
2507    default:
2508      return false;
2509    }
2510    addr_t offset_addr;
2511    if (add)
2512      offset_addr = sp + imm12;
2513    else
2514      offset_addr = sp - imm12;
2515
2516    addr_t addr;
2517    if (index)
2518      addr = offset_addr;
2519    else
2520      addr = sp;
2521
2522    EmulateInstruction::Context context;
2523    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2524    RegisterInfo sp_reg;
2525    RegisterInfo dwarf_reg;
2526
2527    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2528    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2529    context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2530    if (Rt != 15) {
2531      uint32_t reg_value = ReadCoreReg(Rt, &success);
2532      if (!success)
2533        return false;
2534      if (!MemUWrite(context, addr, reg_value, addr_byte_size))
2535        return false;
2536    } else {
2537      const uint32_t pc = ReadCoreReg(PC_REG, &success);
2538      if (!success)
2539        return false;
2540      if (!MemUWrite(context, addr, pc, addr_byte_size))
2541        return false;
2542    }
2543
2544    if (wback) {
2545      context.type = EmulateInstruction::eContextAdjustStackPointer;
2546      context.SetImmediateSigned(addr - sp);
2547      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2548                                 LLDB_REGNUM_GENERIC_SP, offset_addr))
2549        return false;
2550    }
2551  }
2552  return true;
2553}
2554
2555// Vector Push stores multiple extension registers to the stack. It also
2556// updates SP to point to the start of the stored data.
2557bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2558                                         const ARMEncoding encoding) {
2559#if 0
2560    // ARM pseudo code...
2561    if (ConditionPassed())
2562    {
2563        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2564        address = SP - imm32;
2565        SP = SP - imm32;
2566        if single_regs then
2567            for r = 0 to regs-1
2568                MemA[address,4] = S[d+r]; address = address+4;
2569        else
2570            for r = 0 to regs-1
2571                // Store as two word-aligned words in the correct order for
2572                // current endianness.
2573                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2574                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2575                address = address+8;
2576    }
2577#endif
2578
2579  bool success = false;
2580  if (ConditionPassed(opcode)) {
2581    const uint32_t addr_byte_size = GetAddressByteSize();
2582    const addr_t sp = ReadCoreReg(SP_REG, &success);
2583    if (!success)
2584      return false;
2585    bool single_regs;
2586    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2587    uint32_t imm32; // stack offset
2588    uint32_t regs;  // number of registers
2589    switch (encoding) {
2590    case eEncodingT1:
2591    case eEncodingA1:
2592      single_regs = false;
2593      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2594      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2595      // If UInt(imm8) is odd, see "FSTMX".
2596      regs = Bits32(opcode, 7, 0) / 2;
2597      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2598      if (regs == 0 || regs > 16 || (d + regs) > 32)
2599        return false;
2600      break;
2601    case eEncodingT2:
2602    case eEncodingA2:
2603      single_regs = true;
2604      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2605      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2606      regs = Bits32(opcode, 7, 0);
2607      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2608      if (regs == 0 || regs > 16 || (d + regs) > 32)
2609        return false;
2610      break;
2611    default:
2612      return false;
2613    }
2614    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2615    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2616    addr_t sp_offset = imm32;
2617    addr_t addr = sp - sp_offset;
2618    uint32_t i;
2619
2620    EmulateInstruction::Context context;
2621    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2622
2623    RegisterInfo dwarf_reg;
2624    RegisterInfo sp_reg;
2625    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2626    for (i = 0; i < regs; ++i) {
2627      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2628      context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2629      // uint64_t to accommodate 64-bit registers.
2630      uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2631      if (!success)
2632        return false;
2633      if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2634        return false;
2635      addr += reg_byte_size;
2636    }
2637
2638    context.type = EmulateInstruction::eContextAdjustStackPointer;
2639    context.SetImmediateSigned(-sp_offset);
2640
2641    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2642                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2643      return false;
2644  }
2645  return true;
2646}
2647
2648// Vector Pop loads multiple extension registers from the stack. It also
2649// updates SP to point just above the loaded data.
2650bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2651                                        const ARMEncoding encoding) {
2652#if 0
2653    // ARM pseudo code...
2654    if (ConditionPassed())
2655    {
2656        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2657        address = SP;
2658        SP = SP + imm32;
2659        if single_regs then
2660            for r = 0 to regs-1
2661                S[d+r] = MemA[address,4]; address = address+4;
2662        else
2663            for r = 0 to regs-1
2664                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2665                // Combine the word-aligned words in the correct order for
2666                // current endianness.
2667                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2668    }
2669#endif
2670
2671  bool success = false;
2672  if (ConditionPassed(opcode)) {
2673    const uint32_t addr_byte_size = GetAddressByteSize();
2674    const addr_t sp = ReadCoreReg(SP_REG, &success);
2675    if (!success)
2676      return false;
2677    bool single_regs;
2678    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2679    uint32_t imm32; // stack offset
2680    uint32_t regs;  // number of registers
2681    switch (encoding) {
2682    case eEncodingT1:
2683    case eEncodingA1:
2684      single_regs = false;
2685      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2686      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2687      // If UInt(imm8) is odd, see "FLDMX".
2688      regs = Bits32(opcode, 7, 0) / 2;
2689      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2690      if (regs == 0 || regs > 16 || (d + regs) > 32)
2691        return false;
2692      break;
2693    case eEncodingT2:
2694    case eEncodingA2:
2695      single_regs = true;
2696      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2697      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2698      regs = Bits32(opcode, 7, 0);
2699      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2700      if (regs == 0 || regs > 16 || (d + regs) > 32)
2701        return false;
2702      break;
2703    default:
2704      return false;
2705    }
2706    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2707    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2708    addr_t sp_offset = imm32;
2709    addr_t addr = sp;
2710    uint32_t i;
2711    uint64_t data; // uint64_t to accommodate 64-bit registers.
2712
2713    EmulateInstruction::Context context;
2714    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2715
2716    RegisterInfo dwarf_reg;
2717    RegisterInfo sp_reg;
2718    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2719    for (i = 0; i < regs; ++i) {
2720      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2721      context.SetAddress(addr);
2722      data = MemARead(context, addr, reg_byte_size, 0, &success);
2723      if (!success)
2724        return false;
2725      if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2726        return false;
2727      addr += reg_byte_size;
2728    }
2729
2730    context.type = EmulateInstruction::eContextAdjustStackPointer;
2731    context.SetImmediateSigned(sp_offset);
2732
2733    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2734                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2735      return false;
2736  }
2737  return true;
2738}
2739
2740// SVC (previously SWI)
2741bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2742                                       const ARMEncoding encoding) {
2743#if 0
2744    // ARM pseudo code...
2745    if (ConditionPassed())
2746    {
2747        EncodingSpecificOperations();
2748        CallSupervisor();
2749    }
2750#endif
2751
2752  bool success = false;
2753
2754  if (ConditionPassed(opcode)) {
2755    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2756    addr_t lr; // next instruction address
2757    if (!success)
2758      return false;
2759    uint32_t imm32; // the immediate constant
2760    uint32_t mode;  // ARM or Thumb mode
2761    switch (encoding) {
2762    case eEncodingT1:
2763      lr = (pc + 2) | 1u; // return address
2764      imm32 = Bits32(opcode, 7, 0);
2765      mode = eModeThumb;
2766      break;
2767    case eEncodingA1:
2768      lr = pc + 4; // return address
2769      imm32 = Bits32(opcode, 23, 0);
2770      mode = eModeARM;
2771      break;
2772    default:
2773      return false;
2774    }
2775
2776    EmulateInstruction::Context context;
2777    context.type = EmulateInstruction::eContextSupervisorCall;
2778    context.SetISAAndImmediate(mode, imm32);
2779    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2780                               LLDB_REGNUM_GENERIC_RA, lr))
2781      return false;
2782  }
2783  return true;
2784}
2785
2786// If Then makes up to four following instructions (the IT block) conditional.
2787bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2788                                      const ARMEncoding encoding) {
2789#if 0
2790    // ARM pseudo code...
2791    EncodingSpecificOperations();
2792    ITSTATE.IT<7:0> = firstcond:mask;
2793#endif
2794
2795  m_it_session.InitIT(Bits32(opcode, 7, 0));
2796  return true;
2797}
2798
2799bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2800                                       const ARMEncoding encoding) {
2801  // NOP, nothing to do...
2802  return true;
2803}
2804
2805// Branch causes a branch to a target address.
2806bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2807                                     const ARMEncoding encoding) {
2808#if 0
2809    // ARM pseudo code...
2810    if (ConditionPassed())
2811    {
2812        EncodingSpecificOperations();
2813        BranchWritePC(PC + imm32);
2814    }
2815#endif
2816
2817  bool success = false;
2818
2819  if (ConditionPassed(opcode)) {
2820    EmulateInstruction::Context context;
2821    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2822    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2823    if (!success)
2824      return false;
2825    addr_t target; // target address
2826    int32_t imm32; // PC-relative offset
2827    switch (encoding) {
2828    case eEncodingT1:
2829      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2830      imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2831      target = pc + imm32;
2832      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2833      break;
2834    case eEncodingT2:
2835      imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2836      target = pc + imm32;
2837      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2838      break;
2839    case eEncodingT3:
2840      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2841      {
2842        if (Bits32(opcode, 25, 23) == 7)
2843          return false; // See Branches and miscellaneous control on page
2844                        // A6-235.
2845
2846        uint32_t S = Bit32(opcode, 26);
2847        uint32_t imm6 = Bits32(opcode, 21, 16);
2848        uint32_t J1 = Bit32(opcode, 13);
2849        uint32_t J2 = Bit32(opcode, 11);
2850        uint32_t imm11 = Bits32(opcode, 10, 0);
2851        uint32_t imm21 =
2852            (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2853        imm32 = llvm::SignExtend32<21>(imm21);
2854        target = pc + imm32;
2855        context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2856        break;
2857      }
2858    case eEncodingT4: {
2859      uint32_t S = Bit32(opcode, 26);
2860      uint32_t imm10 = Bits32(opcode, 25, 16);
2861      uint32_t J1 = Bit32(opcode, 13);
2862      uint32_t J2 = Bit32(opcode, 11);
2863      uint32_t imm11 = Bits32(opcode, 10, 0);
2864      uint32_t I1 = !(J1 ^ S);
2865      uint32_t I2 = !(J2 ^ S);
2866      uint32_t imm25 =
2867          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2868      imm32 = llvm::SignExtend32<25>(imm25);
2869      target = pc + imm32;
2870      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2871      break;
2872    }
2873    case eEncodingA1:
2874      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2875      target = pc + imm32;
2876      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2877      break;
2878    default:
2879      return false;
2880    }
2881    if (!BranchWritePC(context, target))
2882      return false;
2883  }
2884  return true;
2885}
2886
2887// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2888// value in a register with zero and conditionally branch forward a constant
2889// value.  They do not affect the condition flags. CBNZ, CBZ
2890bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2891                                      const ARMEncoding encoding) {
2892#if 0
2893    // ARM pseudo code...
2894    EncodingSpecificOperations();
2895    if nonzero ^ IsZero(R[n]) then
2896        BranchWritePC(PC + imm32);
2897#endif
2898
2899  bool success = false;
2900
2901  // Read the register value from the operand register Rn.
2902  uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2903  if (!success)
2904    return false;
2905
2906  EmulateInstruction::Context context;
2907  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2908  const uint32_t pc = ReadCoreReg(PC_REG, &success);
2909  if (!success)
2910    return false;
2911
2912  addr_t target;  // target address
2913  uint32_t imm32; // PC-relative offset to branch forward
2914  bool nonzero;
2915  switch (encoding) {
2916  case eEncodingT1:
2917    imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2918    nonzero = BitIsSet(opcode, 11);
2919    target = pc + imm32;
2920    context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2921    break;
2922  default:
2923    return false;
2924  }
2925  if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2926    if (!BranchWritePC(context, target))
2927      return false;
2928
2929  return true;
2930}
2931
2932// Table Branch Byte causes a PC-relative forward branch using a table of
2933// single byte offsets.
2934// A base register provides a pointer to the table, and a second register
2935// supplies an index into the table.
2936// The branch length is twice the value of the byte returned from the table.
2937//
2938// Table Branch Halfword causes a PC-relative forward branch using a table of
2939// single halfword offsets.
2940// A base register provides a pointer to the table, and a second register
2941// supplies an index into the table.
2942// The branch length is twice the value of the halfword returned from the
2943// table. TBB, TBH
2944bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2945                                      const ARMEncoding encoding) {
2946#if 0
2947    // ARM pseudo code...
2948    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2949    if is_tbh then
2950        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2951    else
2952        halfwords = UInt(MemU[R[n]+R[m], 1]);
2953    BranchWritePC(PC + 2*halfwords);
2954#endif
2955
2956  bool success = false;
2957
2958  if (ConditionPassed(opcode)) {
2959    uint32_t Rn; // the base register which contains the address of the table of
2960                 // branch lengths
2961    uint32_t Rm; // the index register which contains an integer pointing to a
2962                 // byte/halfword in the table
2963    bool is_tbh; // true if table branch halfword
2964    switch (encoding) {
2965    case eEncodingT1:
2966      Rn = Bits32(opcode, 19, 16);
2967      Rm = Bits32(opcode, 3, 0);
2968      is_tbh = BitIsSet(opcode, 4);
2969      if (Rn == 13 || BadReg(Rm))
2970        return false;
2971      if (InITBlock() && !LastInITBlock())
2972        return false;
2973      break;
2974    default:
2975      return false;
2976    }
2977
2978    // Read the address of the table from the operand register Rn. The PC can
2979    // be used, in which case the table immediately follows this instruction.
2980    uint32_t base = ReadCoreReg(Rn, &success);
2981    if (!success)
2982      return false;
2983
2984    // the table index
2985    uint32_t index = ReadCoreReg(Rm, &success);
2986    if (!success)
2987      return false;
2988
2989    // the offsetted table address
2990    addr_t addr = base + (is_tbh ? index * 2 : index);
2991
2992    // PC-relative offset to branch forward
2993    EmulateInstruction::Context context;
2994    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2995    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2996    if (!success)
2997      return false;
2998
2999    const uint32_t pc = ReadCoreReg(PC_REG, &success);
3000    if (!success)
3001      return false;
3002
3003    // target address
3004    addr_t target = pc + offset;
3005    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
3006    context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
3007
3008    if (!BranchWritePC(context, target))
3009      return false;
3010  }
3011
3012  return true;
3013}
3014
3015// This instruction adds an immediate value to a register value, and writes the
3016// result to the destination register. It can optionally update the condition
3017// flags based on the result.
3018bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
3019                                               const ARMEncoding encoding) {
3020#if 0
3021    if ConditionPassed() then
3022        EncodingSpecificOperations();
3023        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3024        R[d] = result;
3025        if setflags then
3026            APSR.N = result<31>;
3027            APSR.Z = IsZeroBit(result);
3028            APSR.C = carry;
3029            APSR.V = overflow;
3030#endif
3031
3032  bool success = false;
3033
3034  if (ConditionPassed(opcode)) {
3035    uint32_t d;
3036    uint32_t n;
3037    bool setflags;
3038    uint32_t imm32;
3039    uint32_t carry_out;
3040
3041    // EncodingSpecificOperations();
3042    switch (encoding) {
3043    case eEncodingT1:
3044      // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
3045      // ZeroExtend(imm3, 32);
3046      d = Bits32(opcode, 2, 0);
3047      n = Bits32(opcode, 5, 3);
3048      setflags = !InITBlock();
3049      imm32 = Bits32(opcode, 8, 6);
3050
3051      break;
3052
3053    case eEncodingT2:
3054      // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
3055      // ZeroExtend(imm8, 32);
3056      d = Bits32(opcode, 10, 8);
3057      n = Bits32(opcode, 10, 8);
3058      setflags = !InITBlock();
3059      imm32 = Bits32(opcode, 7, 0);
3060
3061      break;
3062
3063    case eEncodingT3:
3064      // if Rd == '1111' && S == '1' then SEE CMN (immediate);
3065      // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
3066      // ThumbExpandImm(i:imm3:imm8);
3067      d = Bits32(opcode, 11, 8);
3068      n = Bits32(opcode, 19, 16);
3069      setflags = BitIsSet(opcode, 20);
3070      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
3071
3072      // if Rn == '1101' then SEE ADD (SP plus immediate);
3073      if (n == 13)
3074        return EmulateADDSPImm(opcode, eEncodingT3);
3075
3076      // if BadReg(d) || n == 15 then UNPREDICTABLE;
3077      if (BadReg(d) || (n == 15))
3078        return false;
3079
3080      break;
3081
3082    case eEncodingT4: {
3083      // if Rn == '1111' then SEE ADR;
3084      // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
3085      // ZeroExtend(i:imm3:imm8, 32);
3086      d = Bits32(opcode, 11, 8);
3087      n = Bits32(opcode, 19, 16);
3088      setflags = false;
3089      uint32_t i = Bit32(opcode, 26);
3090      uint32_t imm3 = Bits32(opcode, 14, 12);
3091      uint32_t imm8 = Bits32(opcode, 7, 0);
3092      imm32 = (i << 11) | (imm3 << 8) | imm8;
3093
3094      // if Rn == '1101' then SEE ADD (SP plus immediate);
3095      if (n == 13)
3096        return EmulateADDSPImm(opcode, eEncodingT4);
3097
3098      // if BadReg(d) then UNPREDICTABLE;
3099      if (BadReg(d))
3100        return false;
3101
3102      break;
3103    }
3104
3105    default:
3106      return false;
3107    }
3108
3109    uint64_t Rn =
3110        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3111    if (!success)
3112      return false;
3113
3114    //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3115    AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
3116
3117    RegisterInfo reg_n;
3118    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
3119
3120    EmulateInstruction::Context context;
3121    context.type = eContextArithmetic;
3122    context.SetRegisterPlusOffset(reg_n, imm32);
3123
3124    // R[d] = result;
3125    // if setflags then
3126    // APSR.N = result<31>;
3127    // APSR.Z = IsZeroBit(result);
3128    // APSR.C = carry;
3129    // APSR.V = overflow;
3130    if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
3131                                   res.carry_out, res.overflow))
3132      return false;
3133  }
3134  return true;
3135}
3136
3137// This instruction adds an immediate value to a register value, and writes the
3138// result to the destination register.  It can optionally update the condition
3139// flags based on the result.
3140bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
3141                                             const ARMEncoding encoding) {
3142#if 0
3143    // ARM pseudo code...
3144    if ConditionPassed() then
3145        EncodingSpecificOperations();
3146        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3147        if d == 15 then
3148            ALUWritePC(result); // setflags is always FALSE here
3149        else
3150            R[d] = result;
3151            if setflags then
3152                APSR.N = result<31>;
3153                APSR.Z = IsZeroBit(result);
3154                APSR.C = carry;
3155                APSR.V = overflow;
3156#endif
3157
3158  bool success = false;
3159
3160  if (ConditionPassed(opcode)) {
3161    uint32_t Rd, Rn;
3162    uint32_t
3163        imm32; // the immediate value to be added to the value obtained from Rn
3164    bool setflags;
3165    switch (encoding) {
3166    case eEncodingA1:
3167      Rd = Bits32(opcode, 15, 12);
3168      Rn = Bits32(opcode, 19, 16);
3169      setflags = BitIsSet(opcode, 20);
3170      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3171      break;
3172    default:
3173      return false;
3174    }
3175
3176    // Read the first operand.
3177    uint32_t val1 = ReadCoreReg(Rn, &success);
3178    if (!success)
3179      return false;
3180
3181    AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
3182
3183    EmulateInstruction::Context context;
3184    if (Rd == 13)
3185      context.type = EmulateInstruction::eContextAdjustStackPointer;
3186    else if (Rd == GetFramePointerRegisterNumber())
3187      context.type = EmulateInstruction::eContextSetFramePointer;
3188    else
3189      context.type = EmulateInstruction::eContextRegisterPlusOffset;
3190
3191    RegisterInfo dwarf_reg;
3192    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
3193    context.SetRegisterPlusOffset(dwarf_reg, imm32);
3194
3195    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3196                                   res.carry_out, res.overflow))
3197      return false;
3198  }
3199  return true;
3200}
3201
3202// This instruction adds a register value and an optionally-shifted register
3203// value, and writes the result to the destination register. It can optionally
3204// update the condition flags based on the result.
3205bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
3206                                          const ARMEncoding encoding) {
3207#if 0
3208    // ARM pseudo code...
3209    if ConditionPassed() then
3210        EncodingSpecificOperations();
3211        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3212        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3213        if d == 15 then
3214            ALUWritePC(result); // setflags is always FALSE here
3215        else
3216            R[d] = result;
3217            if setflags then
3218                APSR.N = result<31>;
3219                APSR.Z = IsZeroBit(result);
3220                APSR.C = carry;
3221                APSR.V = overflow;
3222#endif
3223
3224  bool success = false;
3225
3226  if (ConditionPassed(opcode)) {
3227    uint32_t Rd, Rn, Rm;
3228    ARM_ShifterType shift_t;
3229    uint32_t shift_n; // the shift applied to the value read from Rm
3230    bool setflags;
3231    switch (encoding) {
3232    case eEncodingT1:
3233      Rd = Bits32(opcode, 2, 0);
3234      Rn = Bits32(opcode, 5, 3);
3235      Rm = Bits32(opcode, 8, 6);
3236      setflags = !InITBlock();
3237      shift_t = SRType_LSL;
3238      shift_n = 0;
3239      break;
3240    case eEncodingT2:
3241      Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3242      Rm = Bits32(opcode, 6, 3);
3243      setflags = false;
3244      shift_t = SRType_LSL;
3245      shift_n = 0;
3246      if (Rn == 15 && Rm == 15)
3247        return false;
3248      if (Rd == 15 && InITBlock() && !LastInITBlock())
3249        return false;
3250      break;
3251    case eEncodingA1:
3252      Rd = Bits32(opcode, 15, 12);
3253      Rn = Bits32(opcode, 19, 16);
3254      Rm = Bits32(opcode, 3, 0);
3255      setflags = BitIsSet(opcode, 20);
3256      shift_n = DecodeImmShiftARM(opcode, shift_t);
3257      break;
3258    default:
3259      return false;
3260    }
3261
3262    // Read the first operand.
3263    uint32_t val1 = ReadCoreReg(Rn, &success);
3264    if (!success)
3265      return false;
3266
3267    // Read the second operand.
3268    uint32_t val2 = ReadCoreReg(Rm, &success);
3269    if (!success)
3270      return false;
3271
3272    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3273    if (!success)
3274      return false;
3275    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3276
3277    EmulateInstruction::Context context;
3278    context.type = eContextArithmetic;
3279    RegisterInfo op1_reg;
3280    RegisterInfo op2_reg;
3281    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
3282    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
3283    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
3284
3285    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
3286                                   res.carry_out, res.overflow))
3287      return false;
3288  }
3289  return true;
3290}
3291
3292// Compare Negative (immediate) adds a register value and an immediate value.
3293// It updates the condition flags based on the result, and discards the result.
3294bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
3295                                          const ARMEncoding encoding) {
3296#if 0
3297    // ARM pseudo code...
3298    if ConditionPassed() then
3299        EncodingSpecificOperations();
3300        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
3301        APSR.N = result<31>;
3302        APSR.Z = IsZeroBit(result);
3303        APSR.C = carry;
3304        APSR.V = overflow;
3305#endif
3306
3307  bool success = false;
3308
3309  uint32_t Rn;    // the first operand
3310  uint32_t imm32; // the immediate value to be compared with
3311  switch (encoding) {
3312  case eEncodingT1:
3313    Rn = Bits32(opcode, 19, 16);
3314    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3315    if (Rn == 15)
3316      return false;
3317    break;
3318  case eEncodingA1:
3319    Rn = Bits32(opcode, 19, 16);
3320    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3321    break;
3322  default:
3323    return false;
3324  }
3325  // Read the register value from the operand register Rn.
3326  uint32_t reg_val = ReadCoreReg(Rn, &success);
3327  if (!success)
3328    return false;
3329
3330  AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
3331
3332  EmulateInstruction::Context context;
3333  context.type = EmulateInstruction::eContextImmediate;
3334  context.SetNoArgs();
3335  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3336}
3337
3338// Compare Negative (register) adds a register value and an optionally-shifted
3339// register value. It updates the condition flags based on the result, and
3340// discards the result.
3341bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
3342                                          const ARMEncoding encoding) {
3343#if 0
3344    // ARM pseudo code...
3345    if ConditionPassed() then
3346        EncodingSpecificOperations();
3347        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3348        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
3349        APSR.N = result<31>;
3350        APSR.Z = IsZeroBit(result);
3351        APSR.C = carry;
3352        APSR.V = overflow;
3353#endif
3354
3355  bool success = false;
3356
3357  uint32_t Rn; // the first operand
3358  uint32_t Rm; // the second operand
3359  ARM_ShifterType shift_t;
3360  uint32_t shift_n; // the shift applied to the value read from Rm
3361  switch (encoding) {
3362  case eEncodingT1:
3363    Rn = Bits32(opcode, 2, 0);
3364    Rm = Bits32(opcode, 5, 3);
3365    shift_t = SRType_LSL;
3366    shift_n = 0;
3367    break;
3368  case eEncodingT2:
3369    Rn = Bits32(opcode, 19, 16);
3370    Rm = Bits32(opcode, 3, 0);
3371    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3372    // if n == 15 || BadReg(m) then UNPREDICTABLE;
3373    if (Rn == 15 || BadReg(Rm))
3374      return false;
3375    break;
3376  case eEncodingA1:
3377    Rn = Bits32(opcode, 19, 16);
3378    Rm = Bits32(opcode, 3, 0);
3379    shift_n = DecodeImmShiftARM(opcode, shift_t);
3380    break;
3381  default:
3382    return false;
3383  }
3384  // Read the register value from register Rn.
3385  uint32_t val1 = ReadCoreReg(Rn, &success);
3386  if (!success)
3387    return false;
3388
3389  // Read the register value from register Rm.
3390  uint32_t val2 = ReadCoreReg(Rm, &success);
3391  if (!success)
3392    return false;
3393
3394  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3395  if (!success)
3396    return false;
3397  AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
3398
3399  EmulateInstruction::Context context;
3400  context.type = EmulateInstruction::eContextImmediate;
3401  context.SetNoArgs();
3402  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3403}
3404
3405// Compare (immediate) subtracts an immediate value from a register value. It
3406// updates the condition flags based on the result, and discards the result.
3407bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
3408                                          const ARMEncoding encoding) {
3409#if 0
3410    // ARM pseudo code...
3411    if ConditionPassed() then
3412        EncodingSpecificOperations();
3413        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
3414        APSR.N = result<31>;
3415        APSR.Z = IsZeroBit(result);
3416        APSR.C = carry;
3417        APSR.V = overflow;
3418#endif
3419
3420  bool success = false;
3421
3422  uint32_t Rn;    // the first operand
3423  uint32_t imm32; // the immediate value to be compared with
3424  switch (encoding) {
3425  case eEncodingT1:
3426    Rn = Bits32(opcode, 10, 8);
3427    imm32 = Bits32(opcode, 7, 0);
3428    break;
3429  case eEncodingT2:
3430    Rn = Bits32(opcode, 19, 16);
3431    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
3432    if (Rn == 15)
3433      return false;
3434    break;
3435  case eEncodingA1:
3436    Rn = Bits32(opcode, 19, 16);
3437    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
3438    break;
3439  default:
3440    return false;
3441  }
3442  // Read the register value from the operand register Rn.
3443  uint32_t reg_val = ReadCoreReg(Rn, &success);
3444  if (!success)
3445    return false;
3446
3447  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
3448
3449  EmulateInstruction::Context context;
3450  context.type = EmulateInstruction::eContextImmediate;
3451  context.SetNoArgs();
3452  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3453}
3454
3455// Compare (register) subtracts an optionally-shifted register value from a
3456// register value. It updates the condition flags based on the result, and
3457// discards the result.
3458bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
3459                                          const ARMEncoding encoding) {
3460#if 0
3461    // ARM pseudo code...
3462    if ConditionPassed() then
3463        EncodingSpecificOperations();
3464        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
3465        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
3466        APSR.N = result<31>;
3467        APSR.Z = IsZeroBit(result);
3468        APSR.C = carry;
3469        APSR.V = overflow;
3470#endif
3471
3472  bool success = false;
3473
3474  uint32_t Rn; // the first operand
3475  uint32_t Rm; // the second operand
3476  ARM_ShifterType shift_t;
3477  uint32_t shift_n; // the shift applied to the value read from Rm
3478  switch (encoding) {
3479  case eEncodingT1:
3480    Rn = Bits32(opcode, 2, 0);
3481    Rm = Bits32(opcode, 5, 3);
3482    shift_t = SRType_LSL;
3483    shift_n = 0;
3484    break;
3485  case eEncodingT2:
3486    Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3487    Rm = Bits32(opcode, 6, 3);
3488    shift_t = SRType_LSL;
3489    shift_n = 0;
3490    if (Rn < 8 && Rm < 8)
3491      return false;
3492    if (Rn == 15 || Rm == 15)
3493      return false;
3494    break;
3495  case eEncodingT3:
3496    Rn = Bits32(opcode, 19, 16);
3497    Rm = Bits32(opcode, 3, 0);
3498    shift_n = DecodeImmShiftThumb(opcode, shift_t);
3499    if (Rn == 15 || BadReg(Rm))
3500      return false;
3501    break;
3502  case eEncodingA1:
3503    Rn = Bits32(opcode, 19, 16);
3504    Rm = Bits32(opcode, 3, 0);
3505    shift_n = DecodeImmShiftARM(opcode, shift_t);
3506    break;
3507  default:
3508    return false;
3509  }
3510  // Read the register value from register Rn.
3511  uint32_t val1 = ReadCoreReg(Rn, &success);
3512  if (!success)
3513    return false;
3514
3515  // Read the register value from register Rm.
3516  uint32_t val2 = ReadCoreReg(Rm, &success);
3517  if (!success)
3518    return false;
3519
3520  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3521  if (!success)
3522    return false;
3523  AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3524
3525  EmulateInstruction::Context context;
3526  context.type = EmulateInstruction::eContextImmediate;
3527  context.SetNoArgs();
3528  return WriteFlags(context, res.result, res.carry_out, res.overflow);
3529}
3530
3531// Arithmetic Shift Right (immediate) shifts a register value right by an
3532// immediate number of bits, shifting in copies of its sign bit, and writes the
3533// result to the destination register.  It can optionally update the condition
3534// flags based on the result.
3535bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3536                                          const ARMEncoding encoding) {
3537#if 0
3538    // ARM pseudo code...
3539    if ConditionPassed() then
3540        EncodingSpecificOperations();
3541        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3542        if d == 15 then         // Can only occur for ARM encoding
3543            ALUWritePC(result); // setflags is always FALSE here
3544        else
3545            R[d] = result;
3546            if setflags then
3547                APSR.N = result<31>;
3548                APSR.Z = IsZeroBit(result);
3549                APSR.C = carry;
3550                // APSR.V unchanged
3551#endif
3552
3553  return EmulateShiftImm(opcode, encoding, SRType_ASR);
3554}
3555
3556// Arithmetic Shift Right (register) shifts a register value right by a
3557// variable number of bits, shifting in copies of its sign bit, and writes the
3558// result to the destination register. The variable number of bits is read from
3559// the bottom byte of a register. It can optionally update the condition flags
3560// based on the result.
3561bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3562                                          const ARMEncoding encoding) {
3563#if 0
3564    // ARM pseudo code...
3565    if ConditionPassed() then
3566        EncodingSpecificOperations();
3567        shift_n = UInt(R[m]<7:0>);
3568        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
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 EmulateShiftReg(opcode, encoding, SRType_ASR);
3578}
3579
3580// Logical Shift Left (immediate) shifts a register value left by an immediate
3581// number of bits, shifting in zeros, and writes the result to the destination
3582// register.  It can optionally update the condition flags based on the result.
3583bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3584                                          const ARMEncoding encoding) {
3585#if 0
3586    // ARM pseudo code...
3587    if ConditionPassed() then
3588        EncodingSpecificOperations();
3589        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3590        if d == 15 then         // Can only occur for ARM encoding
3591            ALUWritePC(result); // setflags is always FALSE here
3592        else
3593            R[d] = result;
3594            if setflags then
3595                APSR.N = result<31>;
3596                APSR.Z = IsZeroBit(result);
3597                APSR.C = carry;
3598                // APSR.V unchanged
3599#endif
3600
3601  return EmulateShiftImm(opcode, encoding, SRType_LSL);
3602}
3603
3604// Logical Shift Left (register) shifts a register value left by a variable
3605// number of bits, shifting in zeros, and writes the result to the destination
3606// register.  The variable number of bits is read from the bottom byte of a
3607// register. It can optionally update the condition flags based on the result.
3608bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3609                                          const ARMEncoding encoding) {
3610#if 0
3611    // ARM pseudo code...
3612    if ConditionPassed() then
3613        EncodingSpecificOperations();
3614        shift_n = UInt(R[m]<7:0>);
3615        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3616        R[d] = result;
3617        if setflags then
3618            APSR.N = result<31>;
3619            APSR.Z = IsZeroBit(result);
3620            APSR.C = carry;
3621            // APSR.V unchanged
3622#endif
3623
3624  return EmulateShiftReg(opcode, encoding, SRType_LSL);
3625}
3626
3627// Logical Shift Right (immediate) shifts a register value right by an
3628// immediate number of bits, shifting in zeros, and writes the result to the
3629// destination register.  It can optionally update the condition flags based on
3630// the result.
3631bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3632                                          const ARMEncoding encoding) {
3633#if 0
3634    // ARM pseudo code...
3635    if ConditionPassed() then
3636        EncodingSpecificOperations();
3637        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3638        if d == 15 then         // Can only occur for ARM encoding
3639            ALUWritePC(result); // setflags is always FALSE here
3640        else
3641            R[d] = result;
3642            if setflags then
3643                APSR.N = result<31>;
3644                APSR.Z = IsZeroBit(result);
3645                APSR.C = carry;
3646                // APSR.V unchanged
3647#endif
3648
3649  return EmulateShiftImm(opcode, encoding, SRType_LSR);
3650}
3651
3652// Logical Shift Right (register) shifts a register value right by a variable
3653// number of bits, shifting in zeros, and writes the result to the destination
3654// register.  The variable number of bits is read from the bottom byte of a
3655// register. It can optionally update the condition flags based on the result.
3656bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3657                                          const ARMEncoding encoding) {
3658#if 0
3659    // ARM pseudo code...
3660    if ConditionPassed() then
3661        EncodingSpecificOperations();
3662        shift_n = UInt(R[m]<7:0>);
3663        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3664        R[d] = result;
3665        if setflags then
3666            APSR.N = result<31>;
3667            APSR.Z = IsZeroBit(result);
3668            APSR.C = carry;
3669            // APSR.V unchanged
3670#endif
3671
3672  return EmulateShiftReg(opcode, encoding, SRType_LSR);
3673}
3674
3675// Rotate Right (immediate) provides the value of the contents of a register
3676// rotated by a constant value. The bits that are rotated off the right end are
3677// inserted into the vacated bit positions on the left. It can optionally
3678// update the condition flags based on the result.
3679bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3680                                          const ARMEncoding encoding) {
3681#if 0
3682    // ARM pseudo code...
3683    if ConditionPassed() then
3684        EncodingSpecificOperations();
3685        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3686        if d == 15 then         // Can only occur for ARM encoding
3687            ALUWritePC(result); // setflags is always FALSE here
3688        else
3689            R[d] = result;
3690            if setflags then
3691                APSR.N = result<31>;
3692                APSR.Z = IsZeroBit(result);
3693                APSR.C = carry;
3694                // APSR.V unchanged
3695#endif
3696
3697  return EmulateShiftImm(opcode, encoding, SRType_ROR);
3698}
3699
3700// Rotate Right (register) provides the value of the contents of a register
3701// rotated by a variable number of bits. The bits that are rotated off the
3702// right end are inserted into the vacated bit positions on the left. The
3703// variable number of bits is read from the bottom byte of a register. It can
3704// optionally update the condition flags based on the result.
3705bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3706                                          const ARMEncoding encoding) {
3707#if 0
3708    // ARM pseudo code...
3709    if ConditionPassed() then
3710        EncodingSpecificOperations();
3711        shift_n = UInt(R[m]<7:0>);
3712        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3713        R[d] = result;
3714        if setflags then
3715            APSR.N = result<31>;
3716            APSR.Z = IsZeroBit(result);
3717            APSR.C = carry;
3718            // APSR.V unchanged
3719#endif
3720
3721  return EmulateShiftReg(opcode, encoding, SRType_ROR);
3722}
3723
3724// Rotate Right with Extend provides the value of the contents of a register
3725// shifted right by one place, with the carry flag shifted into bit [31].
3726//
3727// RRX can optionally update the condition flags based on the result.
3728// In that case, bit [0] is shifted into the carry flag.
3729bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3730                                       const ARMEncoding encoding) {
3731#if 0
3732    // ARM pseudo code...
3733    if ConditionPassed() then
3734        EncodingSpecificOperations();
3735        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3736        if d == 15 then         // Can only occur for ARM encoding
3737            ALUWritePC(result); // setflags is always FALSE here
3738        else
3739            R[d] = result;
3740            if setflags then
3741                APSR.N = result<31>;
3742                APSR.Z = IsZeroBit(result);
3743                APSR.C = carry;
3744                // APSR.V unchanged
3745#endif
3746
3747  return EmulateShiftImm(opcode, encoding, SRType_RRX);
3748}
3749
3750bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3751                                            const ARMEncoding encoding,
3752                                            ARM_ShifterType shift_type) {
3753  //    assert(shift_type == SRType_ASR
3754  //           || shift_type == SRType_LSL
3755  //           || shift_type == SRType_LSR
3756  //           || shift_type == SRType_ROR
3757  //           || shift_type == SRType_RRX);
3758
3759  bool success = false;
3760
3761  if (ConditionPassed(opcode)) {
3762    uint32_t Rd;    // the destination register
3763    uint32_t Rm;    // the first operand register
3764    uint32_t imm5;  // encoding for the shift amount
3765    uint32_t carry; // the carry bit after the shift operation
3766    bool setflags;
3767
3768    // Special case handling!
3769    // A8.6.139 ROR (immediate) -- Encoding T1
3770    ARMEncoding use_encoding = encoding;
3771    if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3772      // Morph the T1 encoding from the ARM Architecture Manual into T2
3773      // encoding to have the same decoding of bit fields as the other Thumb2
3774      // shift operations.
3775      use_encoding = eEncodingT2;
3776    }
3777
3778    switch (use_encoding) {
3779    case eEncodingT1:
3780      // Due to the above special case handling!
3781      if (shift_type == SRType_ROR)
3782        return false;
3783
3784      Rd = Bits32(opcode, 2, 0);
3785      Rm = Bits32(opcode, 5, 3);
3786      setflags = !InITBlock();
3787      imm5 = Bits32(opcode, 10, 6);
3788      break;
3789    case eEncodingT2:
3790      // A8.6.141 RRX
3791      // There's no imm form of RRX instructions.
3792      if (shift_type == SRType_RRX)
3793        return false;
3794
3795      Rd = Bits32(opcode, 11, 8);
3796      Rm = Bits32(opcode, 3, 0);
3797      setflags = BitIsSet(opcode, 20);
3798      imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3799      if (BadReg(Rd) || BadReg(Rm))
3800        return false;
3801      break;
3802    case eEncodingA1:
3803      Rd = Bits32(opcode, 15, 12);
3804      Rm = Bits32(opcode, 3, 0);
3805      setflags = BitIsSet(opcode, 20);
3806      imm5 = Bits32(opcode, 11, 7);
3807      break;
3808    default:
3809      return false;
3810    }
3811
3812    // A8.6.139 ROR (immediate)
3813    if (shift_type == SRType_ROR && imm5 == 0)
3814      shift_type = SRType_RRX;
3815
3816    // Get the first operand.
3817    uint32_t value = ReadCoreReg(Rm, &success);
3818    if (!success)
3819      return false;
3820
3821    // Decode the shift amount if not RRX.
3822    uint32_t amt =
3823        (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3824
3825    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3826    if (!success)
3827      return false;
3828
3829    // The context specifies that an immediate is to be moved into Rd.
3830    EmulateInstruction::Context context;
3831    context.type = EmulateInstruction::eContextImmediate;
3832    context.SetNoArgs();
3833
3834    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3835      return false;
3836  }
3837  return true;
3838}
3839
3840bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3841                                            const ARMEncoding encoding,
3842                                            ARM_ShifterType shift_type) {
3843  // assert(shift_type == SRType_ASR
3844  //        || shift_type == SRType_LSL
3845  //        || shift_type == SRType_LSR
3846  //        || shift_type == SRType_ROR);
3847
3848  bool success = false;
3849
3850  if (ConditionPassed(opcode)) {
3851    uint32_t Rd; // the destination register
3852    uint32_t Rn; // the first operand register
3853    uint32_t
3854        Rm; // the register whose bottom byte contains the amount to shift by
3855    uint32_t carry; // the carry bit after the shift operation
3856    bool setflags;
3857    switch (encoding) {
3858    case eEncodingT1:
3859      Rd = Bits32(opcode, 2, 0);
3860      Rn = Rd;
3861      Rm = Bits32(opcode, 5, 3);
3862      setflags = !InITBlock();
3863      break;
3864    case eEncodingT2:
3865      Rd = Bits32(opcode, 11, 8);
3866      Rn = Bits32(opcode, 19, 16);
3867      Rm = Bits32(opcode, 3, 0);
3868      setflags = BitIsSet(opcode, 20);
3869      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3870        return false;
3871      break;
3872    case eEncodingA1:
3873      Rd = Bits32(opcode, 15, 12);
3874      Rn = Bits32(opcode, 3, 0);
3875      Rm = Bits32(opcode, 11, 8);
3876      setflags = BitIsSet(opcode, 20);
3877      if (Rd == 15 || Rn == 15 || Rm == 15)
3878        return false;
3879      break;
3880    default:
3881      return false;
3882    }
3883
3884    // Get the first operand.
3885    uint32_t value = ReadCoreReg(Rn, &success);
3886    if (!success)
3887      return false;
3888    // Get the Rm register content.
3889    uint32_t val = ReadCoreReg(Rm, &success);
3890    if (!success)
3891      return false;
3892
3893    // Get the shift amount.
3894    uint32_t amt = Bits32(val, 7, 0);
3895
3896    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3897    if (!success)
3898      return false;
3899
3900    // The context specifies that an immediate is to be moved into Rd.
3901    EmulateInstruction::Context context;
3902    context.type = EmulateInstruction::eContextImmediate;
3903    context.SetNoArgs();
3904
3905    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3906      return false;
3907  }
3908  return true;
3909}
3910
3911// LDM loads multiple registers from consecutive memory locations, using an
3912// address from a base register.  Optionally the address just above the highest
3913// of those locations can be written back to the base register.
3914bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3915                                       const ARMEncoding encoding) {
3916#if 0
3917    // ARM pseudo code...
3918    if ConditionPassed()
3919        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3920        address = R[n];
3921
3922        for i = 0 to 14
3923            if registers<i> == '1' then
3924                R[i] = MemA[address, 4]; address = address + 4;
3925        if registers<15> == '1' then
3926            LoadWritePC (MemA[address, 4]);
3927
3928        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3929        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3930
3931#endif
3932
3933  bool success = false;
3934  if (ConditionPassed(opcode)) {
3935    uint32_t n;
3936    uint32_t registers = 0;
3937    bool wback;
3938    const uint32_t addr_byte_size = GetAddressByteSize();
3939    switch (encoding) {
3940    case eEncodingT1:
3941      // n = UInt(Rn); registers = '00000000':register_list; wback =
3942      // (registers<n> == '0');
3943      n = Bits32(opcode, 10, 8);
3944      registers = Bits32(opcode, 7, 0);
3945      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3946      wback = BitIsClear(registers, n);
3947      // if BitCount(registers) < 1 then UNPREDICTABLE;
3948      if (BitCount(registers) < 1)
3949        return false;
3950      break;
3951    case eEncodingT2:
3952      // if W == '1' && Rn == '1101' then SEE POP;
3953      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3954      n = Bits32(opcode, 19, 16);
3955      registers = Bits32(opcode, 15, 0);
3956      registers = registers & 0xdfff; // Make sure bit 13 is zero.
3957      wback = BitIsSet(opcode, 21);
3958
3959      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3960      // UNPREDICTABLE;
3961      if ((n == 15) || (BitCount(registers) < 2) ||
3962          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3963        return false;
3964
3965      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3966      // UNPREDICTABLE;
3967      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3968        return false;
3969
3970      // if wback && registers<n> == '1' then UNPREDICTABLE;
3971      if (wback && BitIsSet(registers, n))
3972        return false;
3973      break;
3974
3975    case eEncodingA1:
3976      n = Bits32(opcode, 19, 16);
3977      registers = Bits32(opcode, 15, 0);
3978      wback = BitIsSet(opcode, 21);
3979      if ((n == 15) || (BitCount(registers) < 1))
3980        return false;
3981      break;
3982    default:
3983      return false;
3984    }
3985
3986    int32_t offset = 0;
3987    const addr_t base_address =
3988        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3989    if (!success)
3990      return false;
3991
3992    EmulateInstruction::Context context;
3993    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3994    RegisterInfo dwarf_reg;
3995    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3996    context.SetRegisterPlusOffset(dwarf_reg, offset);
3997
3998    for (int i = 0; i < 14; ++i) {
3999      if (BitIsSet(registers, i)) {
4000        context.type = EmulateInstruction::eContextRegisterPlusOffset;
4001        context.SetRegisterPlusOffset(dwarf_reg, offset);
4002        if (wback && (n == 13)) // Pop Instruction
4003        {
4004          context.type = EmulateInstruction::eContextPopRegisterOffStack;
4005          context.SetAddress(base_address + offset);
4006        }
4007
4008        // R[i] = MemA [address, 4]; address = address + 4;
4009        uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
4010                                 0, &success);
4011        if (!success)
4012          return false;
4013
4014        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4015                                   data))
4016          return false;
4017
4018        offset += addr_byte_size;
4019      }
4020    }
4021
4022    if (BitIsSet(registers, 15)) {
4023      // LoadWritePC (MemA [address, 4]);
4024      context.type = EmulateInstruction::eContextRegisterPlusOffset;
4025      context.SetRegisterPlusOffset(dwarf_reg, offset);
4026      uint32_t data =
4027          MemARead(context, base_address + offset, addr_byte_size, 0, &success);
4028      if (!success)
4029        return false;
4030      // In ARMv5T and above, this is an interworking branch.
4031      if (!LoadWritePC(context, data))
4032        return false;
4033    }
4034
4035    if (wback && BitIsClear(registers, n)) {
4036      // R[n] = R[n] + 4 * BitCount (registers)
4037      int32_t offset = addr_byte_size * BitCount(registers);
4038      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4039      context.SetRegisterPlusOffset(dwarf_reg, offset);
4040
4041      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4042                                 base_address + offset))
4043        return false;
4044    }
4045    if (wback && BitIsSet(registers, n))
4046      // R[n] bits(32) UNKNOWN;
4047      return WriteBits32Unknown(n);
4048  }
4049  return true;
4050}
4051
4052// LDMDA loads multiple registers from consecutive memory locations using an
4053// address from a base register.
4054// The consecutive memory locations end at this address and the address just
4055// below the lowest of those locations can optionally be written back to the
4056// base register.
4057bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
4058                                         const ARMEncoding encoding) {
4059#if 0
4060    // ARM pseudo code...
4061    if ConditionPassed() then
4062        EncodingSpecificOperations();
4063        address = R[n] - 4*BitCount(registers) + 4;
4064
4065        for i = 0 to 14
4066            if registers<i> == '1' then
4067                  R[i] = MemA[address,4]; address = address + 4;
4068
4069        if registers<15> == '1' then
4070            LoadWritePC(MemA[address,4]);
4071
4072        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4073        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4074#endif
4075
4076  bool success = false;
4077
4078  if (ConditionPassed(opcode)) {
4079    uint32_t n;
4080    uint32_t registers = 0;
4081    bool wback;
4082    const uint32_t addr_byte_size = GetAddressByteSize();
4083
4084    // EncodingSpecificOperations();
4085    switch (encoding) {
4086    case eEncodingA1:
4087      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4088      n = Bits32(opcode, 19, 16);
4089      registers = Bits32(opcode, 15, 0);
4090      wback = BitIsSet(opcode, 21);
4091
4092      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4093      if ((n == 15) || (BitCount(registers) < 1))
4094        return false;
4095
4096      break;
4097
4098    default:
4099      return false;
4100    }
4101    // address = R[n] - 4*BitCount(registers) + 4;
4102
4103    int32_t offset = 0;
4104    addr_t Rn = ReadCoreReg(n, &success);
4105
4106    if (!success)
4107      return false;
4108
4109    addr_t address =
4110        Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
4111
4112    EmulateInstruction::Context context;
4113    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4114    RegisterInfo dwarf_reg;
4115    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4116    context.SetRegisterPlusOffset(dwarf_reg, offset);
4117
4118    // for i = 0 to 14
4119    for (int i = 0; i < 14; ++i) {
4120      // if registers<i> == '1' then
4121      if (BitIsSet(registers, i)) {
4122        // R[i] = MemA[address,4]; address = address + 4;
4123        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4124        uint32_t data =
4125            MemARead(context, address + offset, addr_byte_size, 0, &success);
4126        if (!success)
4127          return false;
4128        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4129                                   data))
4130          return false;
4131        offset += addr_byte_size;
4132      }
4133    }
4134
4135    // if registers<15> == '1' then
4136    //     LoadWritePC(MemA[address,4]);
4137    if (BitIsSet(registers, 15)) {
4138      context.SetRegisterPlusOffset(dwarf_reg, offset);
4139      uint32_t data =
4140          MemARead(context, address + offset, addr_byte_size, 0, &success);
4141      if (!success)
4142        return false;
4143      // In ARMv5T and above, this is an interworking branch.
4144      if (!LoadWritePC(context, data))
4145        return false;
4146    }
4147
4148    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4149    if (wback && BitIsClear(registers, n)) {
4150      if (!success)
4151        return false;
4152
4153      offset = (addr_byte_size * BitCount(registers)) * -1;
4154      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4155      context.SetImmediateSigned(offset);
4156      addr_t addr = Rn + offset;
4157      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4158                                 addr))
4159        return false;
4160    }
4161
4162    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4163    if (wback && BitIsSet(registers, n))
4164      return WriteBits32Unknown(n);
4165  }
4166  return true;
4167}
4168
4169// LDMDB loads multiple registers from consecutive memory locations using an
4170// address from a base register.  The
4171// consecutive memory locations end just below this address, and the address of
4172// the lowest of those locations can be optionally written back to the base
4173// register.
4174bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
4175                                         const ARMEncoding encoding) {
4176#if 0
4177    // ARM pseudo code...
4178    if ConditionPassed() then
4179        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4180        address = R[n] - 4*BitCount(registers);
4181
4182        for i = 0 to 14
4183            if registers<i> == '1' then
4184                  R[i] = MemA[address,4]; address = address + 4;
4185        if registers<15> == '1' then
4186                  LoadWritePC(MemA[address,4]);
4187
4188        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4189        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
4190#endif
4191
4192  bool success = false;
4193
4194  if (ConditionPassed(opcode)) {
4195    uint32_t n;
4196    uint32_t registers = 0;
4197    bool wback;
4198    const uint32_t addr_byte_size = GetAddressByteSize();
4199    switch (encoding) {
4200    case eEncodingT1:
4201      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
4202      n = Bits32(opcode, 19, 16);
4203      registers = Bits32(opcode, 15, 0);
4204      registers = registers & 0xdfff; // Make sure bit 13 is a zero.
4205      wback = BitIsSet(opcode, 21);
4206
4207      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
4208      // UNPREDICTABLE;
4209      if ((n == 15) || (BitCount(registers) < 2) ||
4210          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
4211        return false;
4212
4213      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
4214      // UNPREDICTABLE;
4215      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
4216        return false;
4217
4218      // if wback && registers<n> == '1' then UNPREDICTABLE;
4219      if (wback && BitIsSet(registers, n))
4220        return false;
4221
4222      break;
4223
4224    case eEncodingA1:
4225      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4226      n = Bits32(opcode, 19, 16);
4227      registers = Bits32(opcode, 15, 0);
4228      wback = BitIsSet(opcode, 21);
4229
4230      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4231      if ((n == 15) || (BitCount(registers) < 1))
4232        return false;
4233
4234      break;
4235
4236    default:
4237      return false;
4238    }
4239
4240    // address = R[n] - 4*BitCount(registers);
4241
4242    int32_t offset = 0;
4243    addr_t Rn =
4244        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4245
4246    if (!success)
4247      return false;
4248
4249    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4250    EmulateInstruction::Context context;
4251    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4252    RegisterInfo dwarf_reg;
4253    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4254    context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
4255
4256    for (int i = 0; i < 14; ++i) {
4257      if (BitIsSet(registers, i)) {
4258        // R[i] = MemA[address,4]; address = address + 4;
4259        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
4260        uint32_t data =
4261            MemARead(context, address + offset, addr_byte_size, 0, &success);
4262        if (!success)
4263          return false;
4264
4265        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4266                                   data))
4267          return false;
4268
4269        offset += addr_byte_size;
4270      }
4271    }
4272
4273    // if registers<15> == '1' then
4274    //     LoadWritePC(MemA[address,4]);
4275    if (BitIsSet(registers, 15)) {
4276      context.SetRegisterPlusOffset(dwarf_reg, offset);
4277      uint32_t data =
4278          MemARead(context, address + offset, addr_byte_size, 0, &success);
4279      if (!success)
4280        return false;
4281      // In ARMv5T and above, this is an interworking branch.
4282      if (!LoadWritePC(context, data))
4283        return false;
4284    }
4285
4286    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
4287    if (wback && BitIsClear(registers, n)) {
4288      if (!success)
4289        return false;
4290
4291      offset = (addr_byte_size * BitCount(registers)) * -1;
4292      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4293      context.SetImmediateSigned(offset);
4294      addr_t addr = Rn + offset;
4295      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4296                                 addr))
4297        return false;
4298    }
4299
4300    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4301    // possible for encoding A1
4302    if (wback && BitIsSet(registers, n))
4303      return WriteBits32Unknown(n);
4304  }
4305  return true;
4306}
4307
4308// LDMIB loads multiple registers from consecutive memory locations using an
4309// address from a base register.  The
4310// consecutive memory locations start just above this address, and thea ddress
4311// of the last of those locations can optinoally be written back to the base
4312// register.
4313bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
4314                                         const ARMEncoding encoding) {
4315#if 0
4316    if ConditionPassed() then
4317        EncodingSpecificOperations();
4318        address = R[n] + 4;
4319
4320        for i = 0 to 14
4321            if registers<i> == '1' then
4322                  R[i] = MemA[address,4]; address = address + 4;
4323        if registers<15> == '1' then
4324            LoadWritePC(MemA[address,4]);
4325
4326        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4327        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
4328#endif
4329
4330  bool success = false;
4331
4332  if (ConditionPassed(opcode)) {
4333    uint32_t n;
4334    uint32_t registers = 0;
4335    bool wback;
4336    const uint32_t addr_byte_size = GetAddressByteSize();
4337    switch (encoding) {
4338    case eEncodingA1:
4339      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4340      n = Bits32(opcode, 19, 16);
4341      registers = Bits32(opcode, 15, 0);
4342      wback = BitIsSet(opcode, 21);
4343
4344      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4345      if ((n == 15) || (BitCount(registers) < 1))
4346        return false;
4347
4348      break;
4349    default:
4350      return false;
4351    }
4352    // address = R[n] + 4;
4353
4354    int32_t offset = 0;
4355    addr_t Rn =
4356        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4357
4358    if (!success)
4359      return false;
4360
4361    addr_t address = Rn + addr_byte_size;
4362
4363    EmulateInstruction::Context context;
4364    context.type = EmulateInstruction::eContextRegisterPlusOffset;
4365    RegisterInfo dwarf_reg;
4366    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
4367    context.SetRegisterPlusOffset(dwarf_reg, offset);
4368
4369    for (int i = 0; i < 14; ++i) {
4370      if (BitIsSet(registers, i)) {
4371        // R[i] = MemA[address,4]; address = address + 4;
4372
4373        context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
4374        uint32_t data =
4375            MemARead(context, address + offset, addr_byte_size, 0, &success);
4376        if (!success)
4377          return false;
4378
4379        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
4380                                   data))
4381          return false;
4382
4383        offset += addr_byte_size;
4384      }
4385    }
4386
4387    // if registers<15> == '1' then
4388    //     LoadWritePC(MemA[address,4]);
4389    if (BitIsSet(registers, 15)) {
4390      context.SetRegisterPlusOffset(dwarf_reg, offset);
4391      uint32_t data =
4392          MemARead(context, address + offset, addr_byte_size, 0, &success);
4393      if (!success)
4394        return false;
4395      // In ARMv5T and above, this is an interworking branch.
4396      if (!LoadWritePC(context, data))
4397        return false;
4398    }
4399
4400    // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
4401    if (wback && BitIsClear(registers, n)) {
4402      if (!success)
4403        return false;
4404
4405      offset = addr_byte_size * BitCount(registers);
4406      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4407      context.SetImmediateSigned(offset);
4408      addr_t addr = Rn + offset;
4409      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4410                                 addr))
4411        return false;
4412    }
4413
4414    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
4415    // possible for encoding A1
4416    if (wback && BitIsSet(registers, n))
4417      return WriteBits32Unknown(n);
4418  }
4419  return true;
4420}
4421
4422// Load Register (immediate) calculates an address from a base register value
4423// and an immediate offset, loads a word from memory, and writes to a register.
4424// LDR (immediate, Thumb)
4425bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
4426                                              const ARMEncoding encoding) {
4427#if 0
4428    // ARM pseudo code...
4429    if (ConditionPassed())
4430    {
4431        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
4432        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4433        address = if index then offset_addr else R[n];
4434        data = MemU[address,4];
4435        if wback then R[n] = offset_addr;
4436        if t == 15 then
4437            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
4438        elsif UnalignedSupport() || address<1:0> = '00' then
4439            R[t] = data;
4440        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
4441    }
4442#endif
4443
4444  bool success = false;
4445
4446  if (ConditionPassed(opcode)) {
4447    uint32_t Rt;        // the destination register
4448    uint32_t Rn;        // the base register
4449    uint32_t imm32;     // the immediate offset used to form the address
4450    addr_t offset_addr; // the offset address
4451    addr_t address;     // the calculated address
4452    uint32_t data;      // the literal data value from memory load
4453    bool add, index, wback;
4454    switch (encoding) {
4455    case eEncodingT1:
4456      Rt = Bits32(opcode, 2, 0);
4457      Rn = Bits32(opcode, 5, 3);
4458      imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
4459      // index = TRUE; add = TRUE; wback = FALSE
4460      add = true;
4461      index = true;
4462      wback = false;
4463
4464      break;
4465
4466    case eEncodingT2:
4467      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4468      Rt = Bits32(opcode, 10, 8);
4469      Rn = 13;
4470      imm32 = Bits32(opcode, 7, 0) << 2;
4471
4472      // index = TRUE; add = TRUE; wback = FALSE;
4473      index = true;
4474      add = true;
4475      wback = false;
4476
4477      break;
4478
4479    case eEncodingT3:
4480      // if Rn == '1111' then SEE LDR (literal);
4481      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4482      Rt = Bits32(opcode, 15, 12);
4483      Rn = Bits32(opcode, 19, 16);
4484      imm32 = Bits32(opcode, 11, 0);
4485
4486      // index = TRUE; add = TRUE; wback = FALSE;
4487      index = true;
4488      add = true;
4489      wback = false;
4490
4491      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4492      if ((Rt == 15) && InITBlock() && !LastInITBlock())
4493        return false;
4494
4495      break;
4496
4497    case eEncodingT4:
4498      // if Rn == '1111' then SEE LDR (literal);
4499      // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4500      // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
4501      // '00000100' then SEE POP;
4502      // if P == '0' && W == '0' then UNDEFINED;
4503      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
4504        return false;
4505
4506      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4507      Rt = Bits32(opcode, 15, 12);
4508      Rn = Bits32(opcode, 19, 16);
4509      imm32 = Bits32(opcode, 7, 0);
4510
4511      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4512      index = BitIsSet(opcode, 10);
4513      add = BitIsSet(opcode, 9);
4514      wback = BitIsSet(opcode, 8);
4515
4516      // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4517      // then UNPREDICTABLE;
4518      if ((wback && (Rn == Rt)) ||
4519          ((Rt == 15) && InITBlock() && !LastInITBlock()))
4520        return false;
4521
4522      break;
4523
4524    default:
4525      return false;
4526    }
4527    uint32_t base = ReadCoreReg(Rn, &success);
4528    if (!success)
4529      return false;
4530    if (add)
4531      offset_addr = base + imm32;
4532    else
4533      offset_addr = base - imm32;
4534
4535    address = (index ? offset_addr : base);
4536
4537    RegisterInfo base_reg;
4538    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4539    if (wback) {
4540      EmulateInstruction::Context ctx;
4541      if (Rn == 13) {
4542        ctx.type = eContextAdjustStackPointer;
4543        ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4544      } else if (Rn == GetFramePointerRegisterNumber()) {
4545        ctx.type = eContextSetFramePointer;
4546        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4547      } else {
4548        ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4549        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4550      }
4551
4552      if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4553                                 offset_addr))
4554        return false;
4555    }
4556
4557    // Prepare to write to the Rt register.
4558    EmulateInstruction::Context context;
4559    context.type = EmulateInstruction::eContextRegisterLoad;
4560    context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4561
4562    // Read memory from the address.
4563    data = MemURead(context, address, 4, 0, &success);
4564    if (!success)
4565      return false;
4566
4567    if (Rt == 15) {
4568      if (Bits32(address, 1, 0) == 0) {
4569        if (!LoadWritePC(context, data))
4570          return false;
4571      } else
4572        return false;
4573    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4574      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4575                                 data))
4576        return false;
4577    } else
4578      WriteBits32Unknown(Rt);
4579  }
4580  return true;
4581}
4582
4583// STM (Store Multiple Increment After) stores multiple registers to consecutive
4584// memory locations using an address
4585// from a base register.  The consecutive memory locations start at this
4586// address, and the address just above the last of those locations can
4587// optionally be written back to the base register.
4588bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4589                                       const ARMEncoding encoding) {
4590#if 0
4591    if ConditionPassed() then
4592        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4593        address = R[n];
4594
4595        for i = 0 to 14
4596            if registers<i> == '1' then
4597                if i == n && wback && i != LowestSetBit(registers) then
4598                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4599                else
4600                    MemA[address,4] = R[i];
4601                address = address + 4;
4602
4603        if registers<15> == '1' then // Only possible for encoding A1
4604            MemA[address,4] = PCStoreValue();
4605        if wback then R[n] = R[n] + 4*BitCount(registers);
4606#endif
4607
4608  bool success = false;
4609
4610  if (ConditionPassed(opcode)) {
4611    uint32_t n;
4612    uint32_t registers = 0;
4613    bool wback;
4614    const uint32_t addr_byte_size = GetAddressByteSize();
4615
4616    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4617    switch (encoding) {
4618    case eEncodingT1:
4619      // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4620      n = Bits32(opcode, 10, 8);
4621      registers = Bits32(opcode, 7, 0);
4622      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4623      wback = true;
4624
4625      // if BitCount(registers) < 1 then UNPREDICTABLE;
4626      if (BitCount(registers) < 1)
4627        return false;
4628
4629      break;
4630
4631    case eEncodingT2:
4632      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4633      n = Bits32(opcode, 19, 16);
4634      registers = Bits32(opcode, 15, 0);
4635      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4636      wback = BitIsSet(opcode, 21);
4637
4638      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4639      if ((n == 15) || (BitCount(registers) < 2))
4640        return false;
4641
4642      // if wback && registers<n> == '1' then UNPREDICTABLE;
4643      if (wback && BitIsSet(registers, n))
4644        return false;
4645
4646      break;
4647
4648    case eEncodingA1:
4649      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4650      n = Bits32(opcode, 19, 16);
4651      registers = Bits32(opcode, 15, 0);
4652      wback = BitIsSet(opcode, 21);
4653
4654      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4655      if ((n == 15) || (BitCount(registers) < 1))
4656        return false;
4657
4658      break;
4659
4660    default:
4661      return false;
4662    }
4663
4664    // address = R[n];
4665    int32_t offset = 0;
4666    const addr_t address =
4667        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4668    if (!success)
4669      return false;
4670
4671    EmulateInstruction::Context context;
4672    context.type = EmulateInstruction::eContextRegisterStore;
4673    RegisterInfo base_reg;
4674    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4675
4676    // for i = 0 to 14
4677    uint32_t lowest_set_bit = 14;
4678    for (uint32_t i = 0; i < 14; ++i) {
4679      // if registers<i> == '1' then
4680      if (BitIsSet(registers, i)) {
4681        if (i < lowest_set_bit)
4682          lowest_set_bit = i;
4683        // if i == n && wback && i != LowestSetBit(registers) then
4684        if ((i == n) && wback && (i != lowest_set_bit))
4685          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4686          // T1 and A1
4687          WriteBits32UnknownToMemory(address + offset);
4688        else {
4689          // MemA[address,4] = R[i];
4690          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4691                                               0, &success);
4692          if (!success)
4693            return false;
4694
4695          RegisterInfo data_reg;
4696          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4697          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4698          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4699            return false;
4700        }
4701
4702        // address = address + 4;
4703        offset += addr_byte_size;
4704      }
4705    }
4706
4707    // if registers<15> == '1' then // Only possible for encoding A1
4708    //     MemA[address,4] = PCStoreValue();
4709    if (BitIsSet(registers, 15)) {
4710      RegisterInfo pc_reg;
4711      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4712      context.SetRegisterPlusOffset(pc_reg, 8);
4713      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4714      if (!success)
4715        return false;
4716
4717      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4718        return false;
4719    }
4720
4721    // if wback then R[n] = R[n] + 4*BitCount(registers);
4722    if (wback) {
4723      offset = addr_byte_size * BitCount(registers);
4724      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4725      context.SetImmediateSigned(offset);
4726      addr_t data = address + offset;
4727      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4728                                 data))
4729        return false;
4730    }
4731  }
4732  return true;
4733}
4734
4735// STMDA (Store Multiple Decrement After) stores multiple registers to
4736// consecutive memory locations using an address from a base register.  The
4737// consecutive memory locations end at this address, and the address just below
4738// the lowest of those locations can optionally be written back to the base
4739// register.
4740bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4741                                         const ARMEncoding encoding) {
4742#if 0
4743    if ConditionPassed() then
4744        EncodingSpecificOperations();
4745        address = R[n] - 4*BitCount(registers) + 4;
4746
4747        for i = 0 to 14
4748            if registers<i> == '1' then
4749                if i == n && wback && i != LowestSetBit(registers) then
4750                    MemA[address,4] = bits(32) UNKNOWN;
4751                else
4752                    MemA[address,4] = R[i];
4753                address = address + 4;
4754
4755        if registers<15> == '1' then
4756            MemA[address,4] = PCStoreValue();
4757
4758        if wback then R[n] = R[n] - 4*BitCount(registers);
4759#endif
4760
4761  bool success = false;
4762
4763  if (ConditionPassed(opcode)) {
4764    uint32_t n;
4765    uint32_t registers = 0;
4766    bool wback;
4767    const uint32_t addr_byte_size = GetAddressByteSize();
4768
4769    // EncodingSpecificOperations();
4770    switch (encoding) {
4771    case eEncodingA1:
4772      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4773      n = Bits32(opcode, 19, 16);
4774      registers = Bits32(opcode, 15, 0);
4775      wback = BitIsSet(opcode, 21);
4776
4777      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4778      if ((n == 15) || (BitCount(registers) < 1))
4779        return false;
4780      break;
4781    default:
4782      return false;
4783    }
4784
4785    // address = R[n] - 4*BitCount(registers) + 4;
4786    int32_t offset = 0;
4787    addr_t Rn = ReadCoreReg(n, &success);
4788    if (!success)
4789      return false;
4790
4791    addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4792
4793    EmulateInstruction::Context context;
4794    context.type = EmulateInstruction::eContextRegisterStore;
4795    RegisterInfo base_reg;
4796    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4797
4798    // for i = 0 to 14
4799    uint32_t lowest_bit_set = 14;
4800    for (uint32_t i = 0; i < 14; ++i) {
4801      // if registers<i> == '1' then
4802      if (BitIsSet(registers, i)) {
4803        if (i < lowest_bit_set)
4804          lowest_bit_set = i;
4805        // if i == n && wback && i != LowestSetBit(registers) then
4806        if ((i == n) && wback && (i != lowest_bit_set))
4807          // MemA[address,4] = bits(32) UNKNOWN;
4808          WriteBits32UnknownToMemory(address + offset);
4809        else {
4810          // MemA[address,4] = R[i];
4811          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4812                                               0, &success);
4813          if (!success)
4814            return false;
4815
4816          RegisterInfo data_reg;
4817          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4818          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4819                                                  Rn - (address + offset));
4820          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4821            return false;
4822        }
4823
4824        // address = address + 4;
4825        offset += addr_byte_size;
4826      }
4827    }
4828
4829    // if registers<15> == '1' then
4830    //    MemA[address,4] = PCStoreValue();
4831    if (BitIsSet(registers, 15)) {
4832      RegisterInfo pc_reg;
4833      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4834      context.SetRegisterPlusOffset(pc_reg, 8);
4835      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4836      if (!success)
4837        return false;
4838
4839      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4840        return false;
4841    }
4842
4843    // if wback then R[n] = R[n] - 4*BitCount(registers);
4844    if (wback) {
4845      offset = (addr_byte_size * BitCount(registers)) * -1;
4846      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4847      context.SetImmediateSigned(offset);
4848      addr_t data = Rn + offset;
4849      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4850                                 data))
4851        return false;
4852    }
4853  }
4854  return true;
4855}
4856
4857// STMDB (Store Multiple Decrement Before) stores multiple registers to
4858// consecutive memory locations using an address from a base register.  The
4859// consecutive memory locations end just below this address, and the address of
4860// the first of those locations can optionally be written back to the base
4861// register.
4862bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4863                                         const ARMEncoding encoding) {
4864#if 0
4865    if ConditionPassed() then
4866        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4867        address = R[n] - 4*BitCount(registers);
4868
4869        for i = 0 to 14
4870            if registers<i> == '1' then
4871                if i == n && wback && i != LowestSetBit(registers) then
4872                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4873                else
4874                    MemA[address,4] = R[i];
4875                address = address + 4;
4876
4877        if registers<15> == '1' then // Only possible for encoding A1
4878            MemA[address,4] = PCStoreValue();
4879
4880        if wback then R[n] = R[n] - 4*BitCount(registers);
4881#endif
4882
4883  bool success = false;
4884
4885  if (ConditionPassed(opcode)) {
4886    uint32_t n;
4887    uint32_t registers = 0;
4888    bool wback;
4889    const uint32_t addr_byte_size = GetAddressByteSize();
4890
4891    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4892    switch (encoding) {
4893    case eEncodingT1:
4894      // if W == '1' && Rn == '1101' then SEE PUSH;
4895      if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4896        // See PUSH
4897      }
4898      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4899      n = Bits32(opcode, 19, 16);
4900      registers = Bits32(opcode, 15, 0);
4901      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4902      wback = BitIsSet(opcode, 21);
4903      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4904      if ((n == 15) || BitCount(registers) < 2)
4905        return false;
4906      // if wback && registers<n> == '1' then UNPREDICTABLE;
4907      if (wback && BitIsSet(registers, n))
4908        return false;
4909      break;
4910
4911    case eEncodingA1:
4912      // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4913      // PUSH;
4914      if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4915          BitCount(Bits32(opcode, 15, 0)) >= 2) {
4916        // See Push
4917      }
4918      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4919      n = Bits32(opcode, 19, 16);
4920      registers = Bits32(opcode, 15, 0);
4921      wback = BitIsSet(opcode, 21);
4922      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4923      if ((n == 15) || BitCount(registers) < 1)
4924        return false;
4925      break;
4926
4927    default:
4928      return false;
4929    }
4930
4931    // address = R[n] - 4*BitCount(registers);
4932
4933    int32_t offset = 0;
4934    addr_t Rn =
4935        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4936    if (!success)
4937      return false;
4938
4939    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4940
4941    EmulateInstruction::Context context;
4942    context.type = EmulateInstruction::eContextRegisterStore;
4943    RegisterInfo base_reg;
4944    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4945
4946    // for i = 0 to 14
4947    uint32_t lowest_set_bit = 14;
4948    for (uint32_t i = 0; i < 14; ++i) {
4949      // if registers<i> == '1' then
4950      if (BitIsSet(registers, i)) {
4951        if (i < lowest_set_bit)
4952          lowest_set_bit = i;
4953        // if i == n && wback && i != LowestSetBit(registers) then
4954        if ((i == n) && wback && (i != lowest_set_bit))
4955          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4956          // A1
4957          WriteBits32UnknownToMemory(address + offset);
4958        else {
4959          // MemA[address,4] = R[i];
4960          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4961                                               0, &success);
4962          if (!success)
4963            return false;
4964
4965          RegisterInfo data_reg;
4966          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4967          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4968                                                  Rn - (address + offset));
4969          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4970            return false;
4971        }
4972
4973        // address = address + 4;
4974        offset += addr_byte_size;
4975      }
4976    }
4977
4978    // if registers<15> == '1' then // Only possible for encoding A1
4979    //     MemA[address,4] = PCStoreValue();
4980    if (BitIsSet(registers, 15)) {
4981      RegisterInfo pc_reg;
4982      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4983      context.SetRegisterPlusOffset(pc_reg, 8);
4984      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4985      if (!success)
4986        return false;
4987
4988      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4989        return false;
4990    }
4991
4992    // if wback then R[n] = R[n] - 4*BitCount(registers);
4993    if (wback) {
4994      offset = (addr_byte_size * BitCount(registers)) * -1;
4995      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4996      context.SetImmediateSigned(offset);
4997      addr_t data = Rn + offset;
4998      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4999                                 data))
5000        return false;
5001    }
5002  }
5003  return true;
5004}
5005
5006// STMIB (Store Multiple Increment Before) stores multiple registers to
5007// consecutive memory locations using an address from a base register.  The
5008// consecutive memory locations start just above this address, and the address
5009// of the last of those locations can optionally be written back to the base
5010// register.
5011bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
5012                                         const ARMEncoding encoding) {
5013#if 0
5014    if ConditionPassed() then
5015        EncodingSpecificOperations();
5016        address = R[n] + 4;
5017
5018        for i = 0 to 14
5019            if registers<i> == '1' then
5020                if i == n && wback && i != LowestSetBit(registers) then
5021                    MemA[address,4] = bits(32) UNKNOWN;
5022                else
5023                    MemA[address,4] = R[i];
5024                address = address + 4;
5025
5026        if registers<15> == '1' then
5027            MemA[address,4] = PCStoreValue();
5028
5029        if wback then R[n] = R[n] + 4*BitCount(registers);
5030#endif
5031
5032  bool success = false;
5033
5034  if (ConditionPassed(opcode)) {
5035    uint32_t n;
5036    uint32_t registers = 0;
5037    bool wback;
5038    const uint32_t addr_byte_size = GetAddressByteSize();
5039
5040    // EncodingSpecificOperations();
5041    switch (encoding) {
5042    case eEncodingA1:
5043      // n = UInt(Rn); registers = register_list; wback = (W == '1');
5044      n = Bits32(opcode, 19, 16);
5045      registers = Bits32(opcode, 15, 0);
5046      wback = BitIsSet(opcode, 21);
5047
5048      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
5049      if ((n == 15) && (BitCount(registers) < 1))
5050        return false;
5051      break;
5052    default:
5053      return false;
5054    }
5055    // address = R[n] + 4;
5056
5057    int32_t offset = 0;
5058    addr_t Rn = ReadCoreReg(n, &success);
5059    if (!success)
5060      return false;
5061
5062    addr_t address = Rn + addr_byte_size;
5063
5064    EmulateInstruction::Context context;
5065    context.type = EmulateInstruction::eContextRegisterStore;
5066    RegisterInfo base_reg;
5067    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5068
5069    uint32_t lowest_set_bit = 14;
5070    // for i = 0 to 14
5071    for (uint32_t i = 0; i < 14; ++i) {
5072      // if registers<i> == '1' then
5073      if (BitIsSet(registers, i)) {
5074        if (i < lowest_set_bit)
5075          lowest_set_bit = i;
5076        // if i == n && wback && i != LowestSetBit(registers) then
5077        if ((i == n) && wback && (i != lowest_set_bit))
5078          // MemA[address,4] = bits(32) UNKNOWN;
5079          WriteBits32UnknownToMemory(address + offset);
5080        // else
5081        else {
5082          // MemA[address,4] = R[i];
5083          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
5084                                               0, &success);
5085          if (!success)
5086            return false;
5087
5088          RegisterInfo data_reg;
5089          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
5090          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5091                                                  offset + addr_byte_size);
5092          if (!MemAWrite(context, address + offset, data, addr_byte_size))
5093            return false;
5094        }
5095
5096        // address = address + 4;
5097        offset += addr_byte_size;
5098      }
5099    }
5100
5101    // if registers<15> == '1' then
5102    // MemA[address,4] = PCStoreValue();
5103    if (BitIsSet(registers, 15)) {
5104      RegisterInfo pc_reg;
5105      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
5106      context.SetRegisterPlusOffset(pc_reg, 8);
5107      const uint32_t pc = ReadCoreReg(PC_REG, &success);
5108      if (!success)
5109        return false;
5110
5111      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
5112        return false;
5113    }
5114
5115    // if wback then R[n] = R[n] + 4*BitCount(registers);
5116    if (wback) {
5117      offset = addr_byte_size * BitCount(registers);
5118      context.type = EmulateInstruction::eContextAdjustBaseRegister;
5119      context.SetImmediateSigned(offset);
5120      addr_t data = Rn + offset;
5121      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5122                                 data))
5123        return false;
5124    }
5125  }
5126  return true;
5127}
5128
5129// STR (store immediate) calculates an address from a base register value and an
5130// immediate offset, and stores a word
5131// from a register to memory.  It can use offset, post-indexed, or pre-indexed
5132// addressing.
5133bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
5134                                            const ARMEncoding encoding) {
5135#if 0
5136    if ConditionPassed() then
5137        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5138        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5139        address = if index then offset_addr else R[n];
5140        if UnalignedSupport() || address<1:0> == '00' then
5141            MemU[address,4] = R[t];
5142        else // Can only occur before ARMv7
5143            MemU[address,4] = bits(32) UNKNOWN;
5144        if wback then R[n] = offset_addr;
5145#endif
5146
5147  bool success = false;
5148
5149  if (ConditionPassed(opcode)) {
5150    const uint32_t addr_byte_size = GetAddressByteSize();
5151
5152    uint32_t t;
5153    uint32_t n;
5154    uint32_t imm32;
5155    bool index;
5156    bool add;
5157    bool wback;
5158    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5159    switch (encoding) {
5160    case eEncodingT1:
5161      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
5162      t = Bits32(opcode, 2, 0);
5163      n = Bits32(opcode, 5, 3);
5164      imm32 = Bits32(opcode, 10, 6) << 2;
5165
5166      // index = TRUE; add = TRUE; wback = FALSE;
5167      index = true;
5168      add = false;
5169      wback = false;
5170      break;
5171
5172    case eEncodingT2:
5173      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
5174      t = Bits32(opcode, 10, 8);
5175      n = 13;
5176      imm32 = Bits32(opcode, 7, 0) << 2;
5177
5178      // index = TRUE; add = TRUE; wback = FALSE;
5179      index = true;
5180      add = true;
5181      wback = false;
5182      break;
5183
5184    case eEncodingT3:
5185      // if Rn == '1111' then UNDEFINED;
5186      if (Bits32(opcode, 19, 16) == 15)
5187        return false;
5188
5189      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5190      t = Bits32(opcode, 15, 12);
5191      n = Bits32(opcode, 19, 16);
5192      imm32 = Bits32(opcode, 11, 0);
5193
5194      // index = TRUE; add = TRUE; wback = FALSE;
5195      index = true;
5196      add = true;
5197      wback = false;
5198
5199      // if t == 15 then UNPREDICTABLE;
5200      if (t == 15)
5201        return false;
5202      break;
5203
5204    case eEncodingT4:
5205      // if P == '1' && U == '1' && W == '0' then SEE STRT;
5206      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
5207      // '00000100' then SEE PUSH;
5208      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5209      if ((Bits32(opcode, 19, 16) == 15) ||
5210          (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
5211        return false;
5212
5213      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5214      t = Bits32(opcode, 15, 12);
5215      n = Bits32(opcode, 19, 16);
5216      imm32 = Bits32(opcode, 7, 0);
5217
5218      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5219      index = BitIsSet(opcode, 10);
5220      add = BitIsSet(opcode, 9);
5221      wback = BitIsSet(opcode, 8);
5222
5223      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
5224      if ((t == 15) || (wback && (n == t)))
5225        return false;
5226      break;
5227
5228    default:
5229      return false;
5230    }
5231
5232    addr_t offset_addr;
5233    addr_t address;
5234
5235    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5236    uint32_t base_address = ReadCoreReg(n, &success);
5237    if (!success)
5238      return false;
5239
5240    if (add)
5241      offset_addr = base_address + imm32;
5242    else
5243      offset_addr = base_address - imm32;
5244
5245    // address = if index then offset_addr else R[n];
5246    if (index)
5247      address = offset_addr;
5248    else
5249      address = base_address;
5250
5251    EmulateInstruction::Context context;
5252    if (n == 13)
5253      context.type = eContextPushRegisterOnStack;
5254    else
5255      context.type = eContextRegisterStore;
5256
5257    RegisterInfo base_reg;
5258    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5259
5260    // if UnalignedSupport() || address<1:0> == '00' then
5261    if (UnalignedSupport() ||
5262        (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5263      // MemU[address,4] = R[t];
5264      uint32_t data =
5265          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5266      if (!success)
5267        return false;
5268
5269      RegisterInfo data_reg;
5270      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5271      int32_t offset = address - base_address;
5272      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
5273      if (!MemUWrite(context, address, data, addr_byte_size))
5274        return false;
5275    } else {
5276      // MemU[address,4] = bits(32) UNKNOWN;
5277      WriteBits32UnknownToMemory(address);
5278    }
5279
5280    // if wback then R[n] = offset_addr;
5281    if (wback) {
5282      if (n == 13)
5283        context.type = eContextAdjustStackPointer;
5284      else
5285        context.type = eContextAdjustBaseRegister;
5286      context.SetAddress(offset_addr);
5287
5288      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5289                                 offset_addr))
5290        return false;
5291    }
5292  }
5293  return true;
5294}
5295
5296// STR (Store Register) calculates an address from a base register value and an
5297// offset register value, stores a
5298// word from a register to memory.   The offset register value can optionally
5299// be shifted.
5300bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
5301                                               const ARMEncoding encoding) {
5302#if 0
5303    if ConditionPassed() then
5304        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5305        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5306        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5307        address = if index then offset_addr else R[n];
5308        if t == 15 then // Only possible for encoding A1
5309            data = PCStoreValue();
5310        else
5311            data = R[t];
5312        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
5313            MemU[address,4] = data;
5314        else // Can only occur before ARMv7
5315            MemU[address,4] = bits(32) UNKNOWN;
5316        if wback then R[n] = offset_addr;
5317#endif
5318
5319  bool success = false;
5320
5321  if (ConditionPassed(opcode)) {
5322    const uint32_t addr_byte_size = GetAddressByteSize();
5323
5324    uint32_t t;
5325    uint32_t n;
5326    uint32_t m;
5327    ARM_ShifterType shift_t;
5328    uint32_t shift_n;
5329    bool index;
5330    bool add;
5331    bool wback;
5332
5333    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
5334    switch (encoding) {
5335    case eEncodingT1:
5336      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5337      // in ThumbEE";
5338      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5339      t = Bits32(opcode, 2, 0);
5340      n = Bits32(opcode, 5, 3);
5341      m = Bits32(opcode, 8, 6);
5342
5343      // index = TRUE; add = TRUE; wback = FALSE;
5344      index = true;
5345      add = true;
5346      wback = false;
5347
5348      // (shift_t, shift_n) = (SRType_LSL, 0);
5349      shift_t = SRType_LSL;
5350      shift_n = 0;
5351      break;
5352
5353    case eEncodingT2:
5354      // if Rn == '1111' then UNDEFINED;
5355      if (Bits32(opcode, 19, 16) == 15)
5356        return false;
5357
5358      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5359      t = Bits32(opcode, 15, 12);
5360      n = Bits32(opcode, 19, 16);
5361      m = Bits32(opcode, 3, 0);
5362
5363      // index = TRUE; add = TRUE; wback = FALSE;
5364      index = true;
5365      add = true;
5366      wback = false;
5367
5368      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5369      shift_t = SRType_LSL;
5370      shift_n = Bits32(opcode, 5, 4);
5371
5372      // if t == 15 || BadReg(m) then UNPREDICTABLE;
5373      if ((t == 15) || (BadReg(m)))
5374        return false;
5375      break;
5376
5377    case eEncodingA1: {
5378      // if P == '0' && W == '1' then SEE STRT;
5379      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5380      t = Bits32(opcode, 15, 12);
5381      n = Bits32(opcode, 19, 16);
5382      m = Bits32(opcode, 3, 0);
5383
5384      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5385      // (W == '1');
5386      index = BitIsSet(opcode, 24);
5387      add = BitIsSet(opcode, 23);
5388      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5389
5390      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5391      uint32_t typ = Bits32(opcode, 6, 5);
5392      uint32_t imm5 = Bits32(opcode, 11, 7);
5393      shift_n = DecodeImmShift(typ, imm5, shift_t);
5394
5395      // if m == 15 then UNPREDICTABLE;
5396      if (m == 15)
5397        return false;
5398
5399      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5400      if (wback && ((n == 15) || (n == t)))
5401        return false;
5402
5403      break;
5404    }
5405    default:
5406      return false;
5407    }
5408
5409    addr_t offset_addr;
5410    addr_t address;
5411    int32_t offset = 0;
5412
5413    addr_t base_address =
5414        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5415    if (!success)
5416      return false;
5417
5418    uint32_t Rm_data =
5419        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5420    if (!success)
5421      return false;
5422
5423    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5424    offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
5425    if (!success)
5426      return false;
5427
5428    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5429    if (add)
5430      offset_addr = base_address + offset;
5431    else
5432      offset_addr = base_address - offset;
5433
5434    // address = if index then offset_addr else R[n];
5435    if (index)
5436      address = offset_addr;
5437    else
5438      address = base_address;
5439
5440    uint32_t data;
5441    // if t == 15 then // Only possible for encoding A1
5442    if (t == 15)
5443      // data = PCStoreValue();
5444      data = ReadCoreReg(PC_REG, &success);
5445    else
5446      // data = R[t];
5447      data =
5448          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5449
5450    if (!success)
5451      return false;
5452
5453    EmulateInstruction::Context context;
5454    context.type = eContextRegisterStore;
5455
5456    // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
5457    // InstrSet_ARM then
5458    if (UnalignedSupport() ||
5459        (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
5460        CurrentInstrSet() == eModeARM) {
5461      // MemU[address,4] = data;
5462
5463      RegisterInfo base_reg;
5464      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5465
5466      RegisterInfo data_reg;
5467      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5468
5469      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5470                                              address - base_address);
5471      if (!MemUWrite(context, address, data, addr_byte_size))
5472        return false;
5473
5474    } else
5475      // MemU[address,4] = bits(32) UNKNOWN;
5476      WriteBits32UnknownToMemory(address);
5477
5478    // if wback then R[n] = offset_addr;
5479    if (wback) {
5480      context.type = eContextRegisterLoad;
5481      context.SetAddress(offset_addr);
5482      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5483                                 offset_addr))
5484        return false;
5485    }
5486  }
5487  return true;
5488}
5489
5490bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
5491                                             const ARMEncoding encoding) {
5492#if 0
5493    if ConditionPassed() then
5494        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5495        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5496        address = if index then offset_addr else R[n];
5497        MemU[address,1] = R[t]<7:0>;
5498        if wback then R[n] = offset_addr;
5499#endif
5500
5501  bool success = false;
5502
5503  if (ConditionPassed(opcode)) {
5504    uint32_t t;
5505    uint32_t n;
5506    uint32_t imm32;
5507    bool index;
5508    bool add;
5509    bool wback;
5510    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5511    switch (encoding) {
5512    case eEncodingT1:
5513      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5514      t = Bits32(opcode, 2, 0);
5515      n = Bits32(opcode, 5, 3);
5516      imm32 = Bits32(opcode, 10, 6);
5517
5518      // index = TRUE; add = TRUE; wback = FALSE;
5519      index = true;
5520      add = true;
5521      wback = false;
5522      break;
5523
5524    case eEncodingT2:
5525      // if Rn == '1111' then UNDEFINED;
5526      if (Bits32(opcode, 19, 16) == 15)
5527        return false;
5528
5529      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5530      t = Bits32(opcode, 15, 12);
5531      n = Bits32(opcode, 19, 16);
5532      imm32 = Bits32(opcode, 11, 0);
5533
5534      // index = TRUE; add = TRUE; wback = FALSE;
5535      index = true;
5536      add = true;
5537      wback = false;
5538
5539      // if BadReg(t) then UNPREDICTABLE;
5540      if (BadReg(t))
5541        return false;
5542      break;
5543
5544    case eEncodingT3:
5545      // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5546      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5547      if (Bits32(opcode, 19, 16) == 15)
5548        return false;
5549
5550      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5551      t = Bits32(opcode, 15, 12);
5552      n = Bits32(opcode, 19, 16);
5553      imm32 = Bits32(opcode, 7, 0);
5554
5555      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5556      index = BitIsSet(opcode, 10);
5557      add = BitIsSet(opcode, 9);
5558      wback = BitIsSet(opcode, 8);
5559
5560      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5561      if ((BadReg(t)) || (wback && (n == t)))
5562        return false;
5563      break;
5564
5565    default:
5566      return false;
5567    }
5568
5569    addr_t offset_addr;
5570    addr_t address;
5571    addr_t base_address =
5572        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5573    if (!success)
5574      return false;
5575
5576    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5577    if (add)
5578      offset_addr = base_address + imm32;
5579    else
5580      offset_addr = base_address - imm32;
5581
5582    // address = if index then offset_addr else R[n];
5583    if (index)
5584      address = offset_addr;
5585    else
5586      address = base_address;
5587
5588    // MemU[address,1] = R[t]<7:0>
5589    RegisterInfo base_reg;
5590    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5591
5592    RegisterInfo data_reg;
5593    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5594
5595    EmulateInstruction::Context context;
5596    context.type = eContextRegisterStore;
5597    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5598                                            address - base_address);
5599
5600    uint32_t data =
5601        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5602    if (!success)
5603      return false;
5604
5605    data = Bits32(data, 7, 0);
5606
5607    if (!MemUWrite(context, address, data, 1))
5608      return false;
5609
5610    // if wback then R[n] = offset_addr;
5611    if (wback) {
5612      context.type = eContextRegisterLoad;
5613      context.SetAddress(offset_addr);
5614      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5615                                 offset_addr))
5616        return false;
5617    }
5618  }
5619
5620  return true;
5621}
5622
5623// STRH (register) calculates an address from a base register value and an
5624// offset register value, and stores a
5625// halfword from a register to memory.  The offset register value can be
5626// shifted left by 0, 1, 2, or 3 bits.
5627bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5628                                                const ARMEncoding encoding) {
5629#if 0
5630    if ConditionPassed() then
5631        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5632        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5633        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5634        address = if index then offset_addr else R[n];
5635        if UnalignedSupport() || address<0> == '0' then
5636            MemU[address,2] = R[t]<15:0>;
5637        else // Can only occur before ARMv7
5638            MemU[address,2] = bits(16) UNKNOWN;
5639        if wback then R[n] = offset_addr;
5640#endif
5641
5642  bool success = false;
5643
5644  if (ConditionPassed(opcode)) {
5645    uint32_t t;
5646    uint32_t n;
5647    uint32_t m;
5648    bool index;
5649    bool add;
5650    bool wback;
5651    ARM_ShifterType shift_t;
5652    uint32_t shift_n;
5653
5654    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5655    switch (encoding) {
5656    case eEncodingT1:
5657      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5658      // in ThumbEE";
5659      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5660      t = Bits32(opcode, 2, 0);
5661      n = Bits32(opcode, 5, 3);
5662      m = Bits32(opcode, 8, 6);
5663
5664      // index = TRUE; add = TRUE; wback = FALSE;
5665      index = true;
5666      add = true;
5667      wback = false;
5668
5669      // (shift_t, shift_n) = (SRType_LSL, 0);
5670      shift_t = SRType_LSL;
5671      shift_n = 0;
5672
5673      break;
5674
5675    case eEncodingT2:
5676      // if Rn == '1111' then UNDEFINED;
5677      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5678      t = Bits32(opcode, 15, 12);
5679      n = Bits32(opcode, 19, 16);
5680      m = Bits32(opcode, 3, 0);
5681      if (n == 15)
5682        return false;
5683
5684      // index = TRUE; add = TRUE; wback = FALSE;
5685      index = true;
5686      add = true;
5687      wback = false;
5688
5689      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5690      shift_t = SRType_LSL;
5691      shift_n = Bits32(opcode, 5, 4);
5692
5693      // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5694      if (BadReg(t) || BadReg(m))
5695        return false;
5696
5697      break;
5698
5699    case eEncodingA1:
5700      // if P == '0' && W == '1' then SEE STRHT;
5701      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5702      t = Bits32(opcode, 15, 12);
5703      n = Bits32(opcode, 19, 16);
5704      m = Bits32(opcode, 3, 0);
5705
5706      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
5707      // (W == '1');
5708      index = BitIsSet(opcode, 24);
5709      add = BitIsSet(opcode, 23);
5710      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5711
5712      // (shift_t, shift_n) = (SRType_LSL, 0);
5713      shift_t = SRType_LSL;
5714      shift_n = 0;
5715
5716      // if t == 15 || m == 15 then UNPREDICTABLE;
5717      if ((t == 15) || (m == 15))
5718        return false;
5719
5720      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5721      if (wback && ((n == 15) || (n == t)))
5722        return false;
5723
5724      break;
5725
5726    default:
5727      return false;
5728    }
5729
5730    uint32_t Rm = ReadCoreReg(m, &success);
5731    if (!success)
5732      return false;
5733
5734    uint32_t Rn = ReadCoreReg(n, &success);
5735    if (!success)
5736      return false;
5737
5738    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5739    uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5740    if (!success)
5741      return false;
5742
5743    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5744    addr_t offset_addr;
5745    if (add)
5746      offset_addr = Rn + offset;
5747    else
5748      offset_addr = Rn - offset;
5749
5750    // address = if index then offset_addr else R[n];
5751    addr_t address;
5752    if (index)
5753      address = offset_addr;
5754    else
5755      address = Rn;
5756
5757    EmulateInstruction::Context context;
5758    context.type = eContextRegisterStore;
5759    RegisterInfo base_reg;
5760    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5761    RegisterInfo offset_reg;
5762    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5763
5764    // if UnalignedSupport() || address<0> == '0' then
5765    if (UnalignedSupport() || BitIsClear(address, 0)) {
5766      // MemU[address,2] = R[t]<15:0>;
5767      uint32_t Rt = ReadCoreReg(t, &success);
5768      if (!success)
5769        return false;
5770
5771      EmulateInstruction::Context context;
5772      context.type = eContextRegisterStore;
5773      RegisterInfo base_reg;
5774      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5775      RegisterInfo offset_reg;
5776      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5777      RegisterInfo data_reg;
5778      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5779      context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5780                                                      data_reg);
5781
5782      if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5783        return false;
5784    } else // Can only occur before ARMv7
5785    {
5786      // MemU[address,2] = bits(16) UNKNOWN;
5787    }
5788
5789    // if wback then R[n] = offset_addr;
5790    if (wback) {
5791      context.type = eContextAdjustBaseRegister;
5792      context.SetAddress(offset_addr);
5793      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5794                                 offset_addr))
5795        return false;
5796    }
5797  }
5798
5799  return true;
5800}
5801
5802// Add with Carry (immediate) adds an immediate value and the carry flag value
5803// to a register value, and writes the result to the destination register.  It
5804// can optionally update the condition flags based on the result.
5805bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5806                                          const ARMEncoding encoding) {
5807#if 0
5808    // ARM pseudo code...
5809    if ConditionPassed() then
5810        EncodingSpecificOperations();
5811        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5812        if d == 15 then         // Can only occur for ARM encoding
5813            ALUWritePC(result); // setflags is always FALSE here
5814        else
5815            R[d] = result;
5816            if setflags then
5817                APSR.N = result<31>;
5818                APSR.Z = IsZeroBit(result);
5819                APSR.C = carry;
5820                APSR.V = overflow;
5821#endif
5822
5823  bool success = false;
5824
5825  if (ConditionPassed(opcode)) {
5826    uint32_t Rd, Rn;
5827    uint32_t
5828        imm32; // the immediate value to be added to the value obtained from Rn
5829    bool setflags;
5830    switch (encoding) {
5831    case eEncodingT1:
5832      Rd = Bits32(opcode, 11, 8);
5833      Rn = Bits32(opcode, 19, 16);
5834      setflags = BitIsSet(opcode, 20);
5835      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5836      if (BadReg(Rd) || BadReg(Rn))
5837        return false;
5838      break;
5839    case eEncodingA1:
5840      Rd = Bits32(opcode, 15, 12);
5841      Rn = Bits32(opcode, 19, 16);
5842      setflags = BitIsSet(opcode, 20);
5843      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5844
5845      if (Rd == 15 && setflags)
5846        return EmulateSUBSPcLrEtc(opcode, encoding);
5847      break;
5848    default:
5849      return false;
5850    }
5851
5852    // Read the first operand.
5853    int32_t val1 = ReadCoreReg(Rn, &success);
5854    if (!success)
5855      return false;
5856
5857    AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5858
5859    EmulateInstruction::Context context;
5860    context.type = EmulateInstruction::eContextImmediate;
5861    context.SetNoArgs();
5862
5863    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5864                                   res.carry_out, res.overflow))
5865      return false;
5866  }
5867  return true;
5868}
5869
5870// Add with Carry (register) adds a register value, the carry flag value, and
5871// an optionally-shifted register value, and writes the result to the
5872// destination register.  It can optionally update the condition flags based on
5873// the result.
5874bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5875                                          const ARMEncoding encoding) {
5876#if 0
5877    // ARM pseudo code...
5878    if ConditionPassed() then
5879        EncodingSpecificOperations();
5880        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5881        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5882        if d == 15 then         // Can only occur for ARM encoding
5883            ALUWritePC(result); // setflags is always FALSE here
5884        else
5885            R[d] = result;
5886            if setflags then
5887                APSR.N = result<31>;
5888                APSR.Z = IsZeroBit(result);
5889                APSR.C = carry;
5890                APSR.V = overflow;
5891#endif
5892
5893  bool success = false;
5894
5895  if (ConditionPassed(opcode)) {
5896    uint32_t Rd, Rn, Rm;
5897    ARM_ShifterType shift_t;
5898    uint32_t shift_n; // the shift applied to the value read from Rm
5899    bool setflags;
5900    switch (encoding) {
5901    case eEncodingT1:
5902      Rd = Rn = Bits32(opcode, 2, 0);
5903      Rm = Bits32(opcode, 5, 3);
5904      setflags = !InITBlock();
5905      shift_t = SRType_LSL;
5906      shift_n = 0;
5907      break;
5908    case eEncodingT2:
5909      Rd = Bits32(opcode, 11, 8);
5910      Rn = Bits32(opcode, 19, 16);
5911      Rm = Bits32(opcode, 3, 0);
5912      setflags = BitIsSet(opcode, 20);
5913      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5914      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5915        return false;
5916      break;
5917    case eEncodingA1:
5918      Rd = Bits32(opcode, 15, 12);
5919      Rn = Bits32(opcode, 19, 16);
5920      Rm = Bits32(opcode, 3, 0);
5921      setflags = BitIsSet(opcode, 20);
5922      shift_n = DecodeImmShiftARM(opcode, shift_t);
5923
5924      if (Rd == 15 && setflags)
5925        return EmulateSUBSPcLrEtc(opcode, encoding);
5926      break;
5927    default:
5928      return false;
5929    }
5930
5931    // Read the first operand.
5932    int32_t val1 = ReadCoreReg(Rn, &success);
5933    if (!success)
5934      return false;
5935
5936    // Read the second operand.
5937    int32_t val2 = ReadCoreReg(Rm, &success);
5938    if (!success)
5939      return false;
5940
5941    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5942    if (!success)
5943      return false;
5944    AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5945
5946    EmulateInstruction::Context context;
5947    context.type = EmulateInstruction::eContextImmediate;
5948    context.SetNoArgs();
5949
5950    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5951                                   res.carry_out, res.overflow))
5952      return false;
5953  }
5954  return true;
5955}
5956
5957// This instruction adds an immediate value to the PC value to form a PC-
5958// relative address, and writes the result to the destination register.
5959bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5960                                       const ARMEncoding encoding) {
5961#if 0
5962    // ARM pseudo code...
5963    if ConditionPassed() then
5964        EncodingSpecificOperations();
5965        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5966        if d == 15 then         // Can only occur for ARM encodings
5967            ALUWritePC(result);
5968        else
5969            R[d] = result;
5970#endif
5971
5972  bool success = false;
5973
5974  if (ConditionPassed(opcode)) {
5975    uint32_t Rd;
5976    uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5977    bool add;
5978    switch (encoding) {
5979    case eEncodingT1:
5980      Rd = Bits32(opcode, 10, 8);
5981      imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5982      add = true;
5983      break;
5984    case eEncodingT2:
5985    case eEncodingT3:
5986      Rd = Bits32(opcode, 11, 8);
5987      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5988      add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5989      if (BadReg(Rd))
5990        return false;
5991      break;
5992    case eEncodingA1:
5993    case eEncodingA2:
5994      Rd = Bits32(opcode, 15, 12);
5995      imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
5996      add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5997      break;
5998    default:
5999      return false;
6000    }
6001
6002    // Read the PC value.
6003    uint32_t pc = ReadCoreReg(PC_REG, &success);
6004    if (!success)
6005      return false;
6006
6007    uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
6008
6009    EmulateInstruction::Context context;
6010    context.type = EmulateInstruction::eContextImmediate;
6011    context.SetNoArgs();
6012
6013    if (!WriteCoreReg(context, result, Rd))
6014      return false;
6015  }
6016  return true;
6017}
6018
6019// This instruction performs a bitwise AND of a register value and an immediate
6020// value, and writes the result to the destination register.  It can optionally
6021// update the condition flags based on the result.
6022bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
6023                                          const ARMEncoding encoding) {
6024#if 0
6025    // ARM pseudo code...
6026    if ConditionPassed() then
6027        EncodingSpecificOperations();
6028        result = R[n] AND imm32;
6029        if d == 15 then         // Can only occur for ARM encoding
6030            ALUWritePC(result); // setflags is always FALSE here
6031        else
6032            R[d] = result;
6033            if setflags then
6034                APSR.N = result<31>;
6035                APSR.Z = IsZeroBit(result);
6036                APSR.C = carry;
6037                // APSR.V unchanged
6038#endif
6039
6040  bool success = false;
6041
6042  if (ConditionPassed(opcode)) {
6043    uint32_t Rd, Rn;
6044    uint32_t
6045        imm32; // the immediate value to be ANDed to the value obtained from Rn
6046    bool setflags;
6047    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6048    switch (encoding) {
6049    case eEncodingT1:
6050      Rd = Bits32(opcode, 11, 8);
6051      Rn = Bits32(opcode, 19, 16);
6052      setflags = BitIsSet(opcode, 20);
6053      imm32 = ThumbExpandImm_C(
6054          opcode, APSR_C,
6055          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6056      // if Rd == '1111' && S == '1' then SEE TST (immediate);
6057      if (Rd == 15 && setflags)
6058        return EmulateTSTImm(opcode, eEncodingT1);
6059      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
6060        return false;
6061      break;
6062    case eEncodingA1:
6063      Rd = Bits32(opcode, 15, 12);
6064      Rn = Bits32(opcode, 19, 16);
6065      setflags = BitIsSet(opcode, 20);
6066      imm32 =
6067          ARMExpandImm_C(opcode, APSR_C,
6068                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6069
6070      if (Rd == 15 && setflags)
6071        return EmulateSUBSPcLrEtc(opcode, encoding);
6072      break;
6073    default:
6074      return false;
6075    }
6076
6077    // Read the first operand.
6078    uint32_t val1 = ReadCoreReg(Rn, &success);
6079    if (!success)
6080      return false;
6081
6082    uint32_t result = val1 & imm32;
6083
6084    EmulateInstruction::Context context;
6085    context.type = EmulateInstruction::eContextImmediate;
6086    context.SetNoArgs();
6087
6088    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6089      return false;
6090  }
6091  return true;
6092}
6093
6094// This instruction performs a bitwise AND of a register value and an
6095// optionally-shifted register value, and writes the result to the destination
6096// register.  It can optionally update the condition flags based on the result.
6097bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
6098                                          const ARMEncoding encoding) {
6099#if 0
6100    // ARM pseudo code...
6101    if ConditionPassed() then
6102        EncodingSpecificOperations();
6103        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6104        result = R[n] AND shifted;
6105        if d == 15 then         // Can only occur for ARM encoding
6106            ALUWritePC(result); // setflags is always FALSE here
6107        else
6108            R[d] = result;
6109            if setflags then
6110                APSR.N = result<31>;
6111                APSR.Z = IsZeroBit(result);
6112                APSR.C = carry;
6113                // APSR.V unchanged
6114#endif
6115
6116  bool success = false;
6117
6118  if (ConditionPassed(opcode)) {
6119    uint32_t Rd, Rn, Rm;
6120    ARM_ShifterType shift_t;
6121    uint32_t shift_n; // the shift applied to the value read from Rm
6122    bool setflags;
6123    uint32_t carry;
6124    switch (encoding) {
6125    case eEncodingT1:
6126      Rd = Rn = Bits32(opcode, 2, 0);
6127      Rm = Bits32(opcode, 5, 3);
6128      setflags = !InITBlock();
6129      shift_t = SRType_LSL;
6130      shift_n = 0;
6131      break;
6132    case eEncodingT2:
6133      Rd = Bits32(opcode, 11, 8);
6134      Rn = Bits32(opcode, 19, 16);
6135      Rm = Bits32(opcode, 3, 0);
6136      setflags = BitIsSet(opcode, 20);
6137      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6138      // if Rd == '1111' && S == '1' then SEE TST (register);
6139      if (Rd == 15 && setflags)
6140        return EmulateTSTReg(opcode, eEncodingT2);
6141      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
6142        return false;
6143      break;
6144    case eEncodingA1:
6145      Rd = Bits32(opcode, 15, 12);
6146      Rn = Bits32(opcode, 19, 16);
6147      Rm = Bits32(opcode, 3, 0);
6148      setflags = BitIsSet(opcode, 20);
6149      shift_n = DecodeImmShiftARM(opcode, shift_t);
6150
6151      if (Rd == 15 && setflags)
6152        return EmulateSUBSPcLrEtc(opcode, encoding);
6153      break;
6154    default:
6155      return false;
6156    }
6157
6158    // Read the first operand.
6159    uint32_t val1 = ReadCoreReg(Rn, &success);
6160    if (!success)
6161      return false;
6162
6163    // Read the second operand.
6164    uint32_t val2 = ReadCoreReg(Rm, &success);
6165    if (!success)
6166      return false;
6167
6168    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6169    if (!success)
6170      return false;
6171    uint32_t result = val1 & shifted;
6172
6173    EmulateInstruction::Context context;
6174    context.type = EmulateInstruction::eContextImmediate;
6175    context.SetNoArgs();
6176
6177    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6178      return false;
6179  }
6180  return true;
6181}
6182
6183// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
6184// the complement of an immediate value, and writes the result to the
6185// destination register.  It can optionally update the condition flags based on
6186// the result.
6187bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
6188                                          const ARMEncoding encoding) {
6189#if 0
6190    // ARM pseudo code...
6191    if ConditionPassed() then
6192        EncodingSpecificOperations();
6193        result = R[n] AND NOT(imm32);
6194        if d == 15 then         // Can only occur for ARM encoding
6195            ALUWritePC(result); // setflags is always FALSE here
6196        else
6197            R[d] = result;
6198            if setflags then
6199                APSR.N = result<31>;
6200                APSR.Z = IsZeroBit(result);
6201                APSR.C = carry;
6202                // APSR.V unchanged
6203#endif
6204
6205  bool success = false;
6206
6207  if (ConditionPassed(opcode)) {
6208    uint32_t Rd, Rn;
6209    uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
6210                    // the value obtained from Rn
6211    bool setflags;
6212    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6213    switch (encoding) {
6214    case eEncodingT1:
6215      Rd = Bits32(opcode, 11, 8);
6216      Rn = Bits32(opcode, 19, 16);
6217      setflags = BitIsSet(opcode, 20);
6218      imm32 = ThumbExpandImm_C(
6219          opcode, APSR_C,
6220          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6221      if (BadReg(Rd) || BadReg(Rn))
6222        return false;
6223      break;
6224    case eEncodingA1:
6225      Rd = Bits32(opcode, 15, 12);
6226      Rn = Bits32(opcode, 19, 16);
6227      setflags = BitIsSet(opcode, 20);
6228      imm32 =
6229          ARMExpandImm_C(opcode, APSR_C,
6230                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6231
6232      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6233      // instructions;
6234      if (Rd == 15 && setflags)
6235        return EmulateSUBSPcLrEtc(opcode, encoding);
6236      break;
6237    default:
6238      return false;
6239    }
6240
6241    // Read the first operand.
6242    uint32_t val1 = ReadCoreReg(Rn, &success);
6243    if (!success)
6244      return false;
6245
6246    uint32_t result = val1 & ~imm32;
6247
6248    EmulateInstruction::Context context;
6249    context.type = EmulateInstruction::eContextImmediate;
6250    context.SetNoArgs();
6251
6252    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6253      return false;
6254  }
6255  return true;
6256}
6257
6258// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
6259// the complement of an optionally-shifted register value, and writes the
6260// result to the destination register. It can optionally update the condition
6261// flags based on the result.
6262bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
6263                                          const ARMEncoding encoding) {
6264#if 0
6265    // ARM pseudo code...
6266    if ConditionPassed() then
6267        EncodingSpecificOperations();
6268        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6269        result = R[n] AND NOT(shifted);
6270        if d == 15 then         // Can only occur for ARM encoding
6271            ALUWritePC(result); // setflags is always FALSE here
6272        else
6273            R[d] = result;
6274            if setflags then
6275                APSR.N = result<31>;
6276                APSR.Z = IsZeroBit(result);
6277                APSR.C = carry;
6278                // APSR.V unchanged
6279#endif
6280
6281  bool success = false;
6282
6283  if (ConditionPassed(opcode)) {
6284    uint32_t Rd, Rn, Rm;
6285    ARM_ShifterType shift_t;
6286    uint32_t shift_n; // the shift applied to the value read from Rm
6287    bool setflags;
6288    uint32_t carry;
6289    switch (encoding) {
6290    case eEncodingT1:
6291      Rd = Rn = Bits32(opcode, 2, 0);
6292      Rm = Bits32(opcode, 5, 3);
6293      setflags = !InITBlock();
6294      shift_t = SRType_LSL;
6295      shift_n = 0;
6296      break;
6297    case eEncodingT2:
6298      Rd = Bits32(opcode, 11, 8);
6299      Rn = Bits32(opcode, 19, 16);
6300      Rm = Bits32(opcode, 3, 0);
6301      setflags = BitIsSet(opcode, 20);
6302      shift_n = DecodeImmShiftThumb(opcode, shift_t);
6303      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
6304        return false;
6305      break;
6306    case eEncodingA1:
6307      Rd = Bits32(opcode, 15, 12);
6308      Rn = Bits32(opcode, 19, 16);
6309      Rm = Bits32(opcode, 3, 0);
6310      setflags = BitIsSet(opcode, 20);
6311      shift_n = DecodeImmShiftARM(opcode, shift_t);
6312
6313      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
6314      // instructions;
6315      if (Rd == 15 && setflags)
6316        return EmulateSUBSPcLrEtc(opcode, encoding);
6317      break;
6318    default:
6319      return false;
6320    }
6321
6322    // Read the first operand.
6323    uint32_t val1 = ReadCoreReg(Rn, &success);
6324    if (!success)
6325      return false;
6326
6327    // Read the second operand.
6328    uint32_t val2 = ReadCoreReg(Rm, &success);
6329    if (!success)
6330      return false;
6331
6332    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
6333    if (!success)
6334      return false;
6335    uint32_t result = val1 & ~shifted;
6336
6337    EmulateInstruction::Context context;
6338    context.type = EmulateInstruction::eContextImmediate;
6339    context.SetNoArgs();
6340
6341    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
6342      return false;
6343  }
6344  return true;
6345}
6346
6347// LDR (immediate, ARM) calculates an address from a base register value and an
6348// immediate offset, loads a word
6349// from memory, and writes it to a register.  It can use offset, post-indexed,
6350// or pre-indexed addressing.
6351bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
6352                                                   const ARMEncoding encoding) {
6353#if 0
6354    if ConditionPassed() then
6355        EncodingSpecificOperations();
6356        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6357        address = if index then offset_addr else R[n];
6358        data = MemU[address,4];
6359        if wback then R[n] = offset_addr;
6360        if t == 15 then
6361            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6362        elsif UnalignedSupport() || address<1:0> = '00' then
6363            R[t] = data;
6364        else // Can only apply before ARMv7
6365            R[t] = ROR(data, 8*UInt(address<1:0>));
6366#endif
6367
6368  bool success = false;
6369
6370  if (ConditionPassed(opcode)) {
6371    const uint32_t addr_byte_size = GetAddressByteSize();
6372
6373    uint32_t t;
6374    uint32_t n;
6375    uint32_t imm32;
6376    bool index;
6377    bool add;
6378    bool wback;
6379
6380    switch (encoding) {
6381    case eEncodingA1:
6382      // if Rn == '1111' then SEE LDR (literal);
6383      // if P == '0' && W == '1' then SEE LDRT;
6384      // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
6385      // '000000000100' then SEE POP;
6386      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6387      t = Bits32(opcode, 15, 12);
6388      n = Bits32(opcode, 19, 16);
6389      imm32 = Bits32(opcode, 11, 0);
6390
6391      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6392      // (W == '1');
6393      index = BitIsSet(opcode, 24);
6394      add = BitIsSet(opcode, 23);
6395      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6396
6397      // if wback && n == t then UNPREDICTABLE;
6398      if (wback && (n == t))
6399        return false;
6400
6401      break;
6402
6403    default:
6404      return false;
6405    }
6406
6407    addr_t address;
6408    addr_t offset_addr;
6409    addr_t base_address = ReadCoreReg(n, &success);
6410    if (!success)
6411      return false;
6412
6413    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6414    if (add)
6415      offset_addr = base_address + imm32;
6416    else
6417      offset_addr = base_address - imm32;
6418
6419    // address = if index then offset_addr else R[n];
6420    if (index)
6421      address = offset_addr;
6422    else
6423      address = base_address;
6424
6425    // data = MemU[address,4];
6426
6427    RegisterInfo base_reg;
6428    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6429
6430    EmulateInstruction::Context context;
6431    context.type = eContextRegisterLoad;
6432    context.SetRegisterPlusOffset(base_reg, address - base_address);
6433
6434    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6435    if (!success)
6436      return false;
6437
6438    // if wback then R[n] = offset_addr;
6439    if (wback) {
6440      context.type = eContextAdjustBaseRegister;
6441      context.SetAddress(offset_addr);
6442      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6443                                 offset_addr))
6444        return false;
6445    }
6446
6447    // if t == 15 then
6448    if (t == 15) {
6449      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6450      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6451        // LoadWritePC (data);
6452        context.type = eContextRegisterLoad;
6453        context.SetRegisterPlusOffset(base_reg, address - base_address);
6454        LoadWritePC(context, data);
6455      } else
6456        return false;
6457    }
6458    // elsif UnalignedSupport() || address<1:0> = '00' then
6459    else if (UnalignedSupport() ||
6460             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6461      // R[t] = data;
6462      context.type = eContextRegisterLoad;
6463      context.SetRegisterPlusOffset(base_reg, address - base_address);
6464      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6465                                 data))
6466        return false;
6467    }
6468    // else // Can only apply before ARMv7
6469    else {
6470      // R[t] = ROR(data, 8*UInt(address<1:0>));
6471      data = ROR(data, Bits32(address, 1, 0), &success);
6472      if (!success)
6473        return false;
6474      context.type = eContextRegisterLoad;
6475      context.SetImmediate(data);
6476      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6477                                 data))
6478        return false;
6479    }
6480  }
6481  return true;
6482}
6483
6484// LDR (register) calculates an address from a base register value and an offset
6485// register value, loads a word
6486// from memory, and writes it to a register.  The offset register value can
6487// optionally be shifted.
6488bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
6489                                               const ARMEncoding encoding) {
6490#if 0
6491    if ConditionPassed() then
6492        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6493        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6494        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6495        address = if index then offset_addr else R[n];
6496        data = MemU[address,4];
6497        if wback then R[n] = offset_addr;
6498        if t == 15 then
6499            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6500        elsif UnalignedSupport() || address<1:0> = '00' then
6501            R[t] = data;
6502        else // Can only apply before ARMv7
6503            if CurrentInstrSet() == InstrSet_ARM then
6504                R[t] = ROR(data, 8*UInt(address<1:0>));
6505            else
6506                R[t] = bits(32) UNKNOWN;
6507#endif
6508
6509  bool success = false;
6510
6511  if (ConditionPassed(opcode)) {
6512    const uint32_t addr_byte_size = GetAddressByteSize();
6513
6514    uint32_t t;
6515    uint32_t n;
6516    uint32_t m;
6517    bool index;
6518    bool add;
6519    bool wback;
6520    ARM_ShifterType shift_t;
6521    uint32_t shift_n;
6522
6523    switch (encoding) {
6524    case eEncodingT1:
6525      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6526      // in ThumbEE";
6527      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6528      t = Bits32(opcode, 2, 0);
6529      n = Bits32(opcode, 5, 3);
6530      m = Bits32(opcode, 8, 6);
6531
6532      // index = TRUE; add = TRUE; wback = FALSE;
6533      index = true;
6534      add = true;
6535      wback = false;
6536
6537      // (shift_t, shift_n) = (SRType_LSL, 0);
6538      shift_t = SRType_LSL;
6539      shift_n = 0;
6540
6541      break;
6542
6543    case eEncodingT2:
6544      // if Rn == '1111' then SEE LDR (literal);
6545      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6546      t = Bits32(opcode, 15, 12);
6547      n = Bits32(opcode, 19, 16);
6548      m = Bits32(opcode, 3, 0);
6549
6550      // index = TRUE; add = TRUE; wback = FALSE;
6551      index = true;
6552      add = true;
6553      wback = false;
6554
6555      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6556      shift_t = SRType_LSL;
6557      shift_n = Bits32(opcode, 5, 4);
6558
6559      // if BadReg(m) then UNPREDICTABLE;
6560      if (BadReg(m))
6561        return false;
6562
6563      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6564      if ((t == 15) && InITBlock() && !LastInITBlock())
6565        return false;
6566
6567      break;
6568
6569    case eEncodingA1: {
6570      // if P == '0' && W == '1' then SEE LDRT;
6571      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6572      t = Bits32(opcode, 15, 12);
6573      n = Bits32(opcode, 19, 16);
6574      m = Bits32(opcode, 3, 0);
6575
6576      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
6577      // (W == '1');
6578      index = BitIsSet(opcode, 24);
6579      add = BitIsSet(opcode, 23);
6580      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6581
6582      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6583      uint32_t type = Bits32(opcode, 6, 5);
6584      uint32_t imm5 = Bits32(opcode, 11, 7);
6585      shift_n = DecodeImmShift(type, imm5, shift_t);
6586
6587      // if m == 15 then UNPREDICTABLE;
6588      if (m == 15)
6589        return false;
6590
6591      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6592      if (wback && ((n == 15) || (n == t)))
6593        return false;
6594    } break;
6595
6596    default:
6597      return false;
6598    }
6599
6600    uint32_t Rm =
6601        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6602    if (!success)
6603      return false;
6604
6605    uint32_t Rn =
6606        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6607    if (!success)
6608      return false;
6609
6610    addr_t offset_addr;
6611    addr_t address;
6612
6613    // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is
6614    // an application level alias for the CPSR".
6615    addr_t offset =
6616        Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6617    if (!success)
6618      return false;
6619
6620    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6621    if (add)
6622      offset_addr = Rn + offset;
6623    else
6624      offset_addr = Rn - offset;
6625
6626    // address = if index then offset_addr else R[n];
6627    if (index)
6628      address = offset_addr;
6629    else
6630      address = Rn;
6631
6632    // data = MemU[address,4];
6633    RegisterInfo base_reg;
6634    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6635
6636    EmulateInstruction::Context context;
6637    context.type = eContextRegisterLoad;
6638    context.SetRegisterPlusOffset(base_reg, address - Rn);
6639
6640    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6641    if (!success)
6642      return false;
6643
6644    // if wback then R[n] = offset_addr;
6645    if (wback) {
6646      context.type = eContextAdjustBaseRegister;
6647      context.SetAddress(offset_addr);
6648      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6649                                 offset_addr))
6650        return false;
6651    }
6652
6653    // if t == 15 then
6654    if (t == 15) {
6655      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6656      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6657        context.type = eContextRegisterLoad;
6658        context.SetRegisterPlusOffset(base_reg, address - Rn);
6659        LoadWritePC(context, data);
6660      } else
6661        return false;
6662    }
6663    // elsif UnalignedSupport() || address<1:0> = '00' then
6664    else if (UnalignedSupport() ||
6665             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6666      // R[t] = data;
6667      context.type = eContextRegisterLoad;
6668      context.SetRegisterPlusOffset(base_reg, address - Rn);
6669      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6670                                 data))
6671        return false;
6672    } else // Can only apply before ARMv7
6673    {
6674      // if CurrentInstrSet() == InstrSet_ARM then
6675      if (CurrentInstrSet() == eModeARM) {
6676        // R[t] = ROR(data, 8*UInt(address<1:0>));
6677        data = ROR(data, Bits32(address, 1, 0), &success);
6678        if (!success)
6679          return false;
6680        context.type = eContextRegisterLoad;
6681        context.SetImmediate(data);
6682        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6683                                   data))
6684          return false;
6685      } else {
6686        // R[t] = bits(32) UNKNOWN;
6687        WriteBits32Unknown(t);
6688      }
6689    }
6690  }
6691  return true;
6692}
6693
6694// LDRB (immediate, Thumb)
6695bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6696                                                 const ARMEncoding encoding) {
6697#if 0
6698    if ConditionPassed() then
6699        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6700        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6701        address = if index then offset_addr else R[n];
6702        R[t] = ZeroExtend(MemU[address,1], 32);
6703        if wback then R[n] = offset_addr;
6704#endif
6705
6706  bool success = false;
6707
6708  if (ConditionPassed(opcode)) {
6709    uint32_t t;
6710    uint32_t n;
6711    uint32_t imm32;
6712    bool index;
6713    bool add;
6714    bool wback;
6715
6716    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6717    switch (encoding) {
6718    case eEncodingT1:
6719      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6720      t = Bits32(opcode, 2, 0);
6721      n = Bits32(opcode, 5, 3);
6722      imm32 = Bits32(opcode, 10, 6);
6723
6724      // index = TRUE; add = TRUE; wback = FALSE;
6725      index = true;
6726      add = true;
6727      wback = false;
6728
6729      break;
6730
6731    case eEncodingT2:
6732      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6733      t = Bits32(opcode, 15, 12);
6734      n = Bits32(opcode, 19, 16);
6735      imm32 = Bits32(opcode, 11, 0);
6736
6737      // index = TRUE; add = TRUE; wback = FALSE;
6738      index = true;
6739      add = true;
6740      wback = false;
6741
6742      // if Rt == '1111' then SEE PLD;
6743      if (t == 15)
6744        return false; // PLD is not implemented yet
6745
6746      // if Rn == '1111' then SEE LDRB (literal);
6747      if (n == 15)
6748        return EmulateLDRBLiteral(opcode, eEncodingT1);
6749
6750      // if t == 13 then UNPREDICTABLE;
6751      if (t == 13)
6752        return false;
6753
6754      break;
6755
6756    case eEncodingT3:
6757      // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6758      // if P == '0' && W == '0' then UNDEFINED;
6759      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6760        return false;
6761
6762      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6763      t = Bits32(opcode, 15, 12);
6764      n = Bits32(opcode, 19, 16);
6765      imm32 = Bits32(opcode, 7, 0);
6766
6767      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6768      index = BitIsSet(opcode, 10);
6769      add = BitIsSet(opcode, 9);
6770      wback = BitIsSet(opcode, 8);
6771
6772      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6773      if (t == 15)
6774        return false; // PLD is not implemented yet
6775
6776      // if Rn == '1111' then SEE LDRB (literal);
6777      if (n == 15)
6778        return EmulateLDRBLiteral(opcode, eEncodingT1);
6779
6780      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6781      if (BadReg(t) || (wback && (n == t)))
6782        return false;
6783
6784      break;
6785
6786    default:
6787      return false;
6788    }
6789
6790    uint32_t Rn =
6791        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6792    if (!success)
6793      return false;
6794
6795    addr_t address;
6796    addr_t offset_addr;
6797
6798    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6799    if (add)
6800      offset_addr = Rn + imm32;
6801    else
6802      offset_addr = Rn - imm32;
6803
6804    // address = if index then offset_addr else R[n];
6805    if (index)
6806      address = offset_addr;
6807    else
6808      address = Rn;
6809
6810    // R[t] = ZeroExtend(MemU[address,1], 32);
6811    RegisterInfo base_reg;
6812    RegisterInfo data_reg;
6813    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6814    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6815
6816    EmulateInstruction::Context context;
6817    context.type = eContextRegisterLoad;
6818    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6819
6820    uint64_t data = MemURead(context, address, 1, 0, &success);
6821    if (!success)
6822      return false;
6823
6824    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6825      return false;
6826
6827    // if wback then R[n] = offset_addr;
6828    if (wback) {
6829      context.type = eContextAdjustBaseRegister;
6830      context.SetAddress(offset_addr);
6831      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6832                                 offset_addr))
6833        return false;
6834    }
6835  }
6836  return true;
6837}
6838
6839// LDRB (literal) calculates an address from the PC value and an immediate
6840// offset, loads a byte from memory,
6841// zero-extends it to form a 32-bit word and writes it to a register.
6842bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6843                                               const ARMEncoding encoding) {
6844#if 0
6845    if ConditionPassed() then
6846        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6847        base = Align(PC,4);
6848        address = if add then (base + imm32) else (base - imm32);
6849        R[t] = ZeroExtend(MemU[address,1], 32);
6850#endif
6851
6852  bool success = false;
6853
6854  if (ConditionPassed(opcode)) {
6855    uint32_t t;
6856    uint32_t imm32;
6857    bool add;
6858    switch (encoding) {
6859    case eEncodingT1:
6860      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6861      t = Bits32(opcode, 15, 12);
6862      imm32 = Bits32(opcode, 11, 0);
6863      add = BitIsSet(opcode, 23);
6864
6865      // if Rt == '1111' then SEE PLD;
6866      if (t == 15)
6867        return false; // PLD is not implemented yet
6868
6869      // if t == 13 then UNPREDICTABLE;
6870      if (t == 13)
6871        return false;
6872
6873      break;
6874
6875    case eEncodingA1:
6876      // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6877      t = Bits32(opcode, 15, 12);
6878      imm32 = Bits32(opcode, 11, 0);
6879      add = BitIsSet(opcode, 23);
6880
6881      // if t == 15 then UNPREDICTABLE;
6882      if (t == 15)
6883        return false;
6884      break;
6885
6886    default:
6887      return false;
6888    }
6889
6890    // base = Align(PC,4);
6891    uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6892    if (!success)
6893      return false;
6894
6895    uint32_t base = AlignPC(pc_val);
6896
6897    addr_t address;
6898    // address = if add then (base + imm32) else (base - imm32);
6899    if (add)
6900      address = base + imm32;
6901    else
6902      address = base - imm32;
6903
6904    // R[t] = ZeroExtend(MemU[address,1], 32);
6905    EmulateInstruction::Context context;
6906    context.type = eContextRelativeBranchImmediate;
6907    context.SetImmediate(address - base);
6908
6909    uint64_t data = MemURead(context, address, 1, 0, &success);
6910    if (!success)
6911      return false;
6912
6913    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6914      return false;
6915  }
6916  return true;
6917}
6918
6919// LDRB (register) calculates an address from a base register value and an
6920// offset rigister value, loads a byte from memory, zero-extends it to form a
6921// 32-bit word, and writes it to a register. The offset register value can
6922// optionally be shifted.
6923bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6924                                                const ARMEncoding encoding) {
6925#if 0
6926    if ConditionPassed() then
6927        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6928        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6929        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6930        address = if index then offset_addr else R[n];
6931        R[t] = ZeroExtend(MemU[address,1],32);
6932        if wback then R[n] = offset_addr;
6933#endif
6934
6935  bool success = false;
6936
6937  if (ConditionPassed(opcode)) {
6938    uint32_t t;
6939    uint32_t n;
6940    uint32_t m;
6941    bool index;
6942    bool add;
6943    bool wback;
6944    ARM_ShifterType shift_t;
6945    uint32_t shift_n;
6946
6947    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6948    switch (encoding) {
6949    case eEncodingT1:
6950      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6951      t = Bits32(opcode, 2, 0);
6952      n = Bits32(opcode, 5, 3);
6953      m = Bits32(opcode, 8, 6);
6954
6955      // index = TRUE; add = TRUE; wback = FALSE;
6956      index = true;
6957      add = true;
6958      wback = false;
6959
6960      // (shift_t, shift_n) = (SRType_LSL, 0);
6961      shift_t = SRType_LSL;
6962      shift_n = 0;
6963      break;
6964
6965    case eEncodingT2:
6966      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6967      t = Bits32(opcode, 15, 12);
6968      n = Bits32(opcode, 19, 16);
6969      m = Bits32(opcode, 3, 0);
6970
6971      // index = TRUE; add = TRUE; wback = FALSE;
6972      index = true;
6973      add = true;
6974      wback = false;
6975
6976      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6977      shift_t = SRType_LSL;
6978      shift_n = Bits32(opcode, 5, 4);
6979
6980      // if Rt == '1111' then SEE PLD;
6981      if (t == 15)
6982        return false; // PLD is not implemented yet
6983
6984      // if Rn == '1111' then SEE LDRB (literal);
6985      if (n == 15)
6986        return EmulateLDRBLiteral(opcode, eEncodingT1);
6987
6988      // if t == 13 || BadReg(m) then UNPREDICTABLE;
6989      if ((t == 13) || BadReg(m))
6990        return false;
6991      break;
6992
6993    case eEncodingA1: {
6994      // if P == '0' && W == '1' then SEE LDRBT;
6995      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6996      t = Bits32(opcode, 15, 12);
6997      n = Bits32(opcode, 19, 16);
6998      m = Bits32(opcode, 3, 0);
6999
7000      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7001      // (W == '1');
7002      index = BitIsSet(opcode, 24);
7003      add = BitIsSet(opcode, 23);
7004      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7005
7006      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
7007      uint32_t type = Bits32(opcode, 6, 5);
7008      uint32_t imm5 = Bits32(opcode, 11, 7);
7009      shift_n = DecodeImmShift(type, imm5, shift_t);
7010
7011      // if t == 15 || m == 15 then UNPREDICTABLE;
7012      if ((t == 15) || (m == 15))
7013        return false;
7014
7015      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7016      if (wback && ((n == 15) || (n == t)))
7017        return false;
7018    } break;
7019
7020    default:
7021      return false;
7022    }
7023
7024    addr_t offset_addr;
7025    addr_t address;
7026
7027    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7028    uint32_t Rm =
7029        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7030    if (!success)
7031      return false;
7032
7033    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7034    if (!success)
7035      return false;
7036
7037    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7038    uint32_t Rn =
7039        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7040    if (!success)
7041      return false;
7042
7043    if (add)
7044      offset_addr = Rn + offset;
7045    else
7046      offset_addr = Rn - offset;
7047
7048    // address = if index then offset_addr else R[n];
7049    if (index)
7050      address = offset_addr;
7051    else
7052      address = Rn;
7053
7054    // R[t] = ZeroExtend(MemU[address,1],32);
7055    RegisterInfo base_reg;
7056    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7057
7058    EmulateInstruction::Context context;
7059    context.type = eContextRegisterLoad;
7060    context.SetRegisterPlusOffset(base_reg, address - Rn);
7061
7062    uint64_t data = MemURead(context, address, 1, 0, &success);
7063    if (!success)
7064      return false;
7065
7066    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
7067      return false;
7068
7069    // if wback then R[n] = offset_addr;
7070    if (wback) {
7071      context.type = eContextAdjustBaseRegister;
7072      context.SetAddress(offset_addr);
7073      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7074                                 offset_addr))
7075        return false;
7076    }
7077  }
7078  return true;
7079}
7080
7081// LDRH (immediate, Thumb) calculates an address from a base register value and
7082// an immediate offset, loads a
7083// halfword from memory, zero-extends it to form a 32-bit word, and writes it
7084// to a register.  It can use offset, post-indexed, or pre-indexed addressing.
7085bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
7086                                                 const ARMEncoding encoding) {
7087#if 0
7088    if ConditionPassed() then
7089        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7090        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7091        address = if index then offset_addr else R[n];
7092        data = MemU[address,2];
7093        if wback then R[n] = offset_addr;
7094        if UnalignedSupport() || address<0> = '0' then
7095            R[t] = ZeroExtend(data, 32);
7096        else // Can only apply before ARMv7
7097            R[t] = bits(32) UNKNOWN;
7098#endif
7099
7100  bool success = false;
7101
7102  if (ConditionPassed(opcode)) {
7103    uint32_t t;
7104    uint32_t n;
7105    uint32_t imm32;
7106    bool index;
7107    bool add;
7108    bool wback;
7109
7110    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7111    switch (encoding) {
7112    case eEncodingT1:
7113      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
7114      t = Bits32(opcode, 2, 0);
7115      n = Bits32(opcode, 5, 3);
7116      imm32 = Bits32(opcode, 10, 6) << 1;
7117
7118      // index = TRUE; add = TRUE; wback = FALSE;
7119      index = true;
7120      add = true;
7121      wback = false;
7122
7123      break;
7124
7125    case eEncodingT2:
7126      // if Rt == '1111' then SEE "Unallocated memory hints";
7127      // if Rn == '1111' then SEE LDRH (literal);
7128      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7129      t = Bits32(opcode, 15, 12);
7130      n = Bits32(opcode, 19, 16);
7131      imm32 = Bits32(opcode, 11, 0);
7132
7133      // index = TRUE; add = TRUE; wback = FALSE;
7134      index = true;
7135      add = true;
7136      wback = false;
7137
7138      // if t == 13 then UNPREDICTABLE;
7139      if (t == 13)
7140        return false;
7141      break;
7142
7143    case eEncodingT3:
7144      // if Rn == '1111' then SEE LDRH (literal);
7145      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7146      // "Unallocated memory hints";
7147      // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
7148      // if P == '0' && W == '0' then UNDEFINED;
7149      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7150        return false;
7151
7152      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7153      t = Bits32(opcode, 15, 12);
7154      n = Bits32(opcode, 19, 16);
7155      imm32 = Bits32(opcode, 7, 0);
7156
7157      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7158      index = BitIsSet(opcode, 10);
7159      add = BitIsSet(opcode, 9);
7160      wback = BitIsSet(opcode, 8);
7161
7162      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7163      if (BadReg(t) || (wback && (n == t)))
7164        return false;
7165      break;
7166
7167    default:
7168      return false;
7169    }
7170
7171    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7172    uint32_t Rn =
7173        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7174    if (!success)
7175      return false;
7176
7177    addr_t offset_addr;
7178    addr_t address;
7179
7180    if (add)
7181      offset_addr = Rn + imm32;
7182    else
7183      offset_addr = Rn - imm32;
7184
7185    // address = if index then offset_addr else R[n];
7186    if (index)
7187      address = offset_addr;
7188    else
7189      address = Rn;
7190
7191    // data = MemU[address,2];
7192    RegisterInfo base_reg;
7193    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7194
7195    EmulateInstruction::Context context;
7196    context.type = eContextRegisterLoad;
7197    context.SetRegisterPlusOffset(base_reg, address - Rn);
7198
7199    uint64_t data = MemURead(context, address, 2, 0, &success);
7200    if (!success)
7201      return false;
7202
7203    // if wback then R[n] = offset_addr;
7204    if (wback) {
7205      context.type = eContextAdjustBaseRegister;
7206      context.SetAddress(offset_addr);
7207      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7208                                 offset_addr))
7209        return false;
7210    }
7211
7212    // if UnalignedSupport() || address<0> = '0' then
7213    if (UnalignedSupport() || BitIsClear(address, 0)) {
7214      // R[t] = ZeroExtend(data, 32);
7215      context.type = eContextRegisterLoad;
7216      context.SetRegisterPlusOffset(base_reg, address - Rn);
7217      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7218                                 data))
7219        return false;
7220    } else // Can only apply before ARMv7
7221    {
7222      // R[t] = bits(32) UNKNOWN;
7223      WriteBits32Unknown(t);
7224    }
7225  }
7226  return true;
7227}
7228
7229// LDRH (literal) caculates an address from the PC value and an immediate
7230// offset, loads a halfword from memory,
7231// zero-extends it to form a 32-bit word, and writes it to a register.
7232bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
7233                                               const ARMEncoding encoding) {
7234#if 0
7235    if ConditionPassed() then
7236        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7237        base = Align(PC,4);
7238        address = if add then (base + imm32) else (base - imm32);
7239        data = MemU[address,2];
7240        if UnalignedSupport() || address<0> = '0' then
7241            R[t] = ZeroExtend(data, 32);
7242        else // Can only apply before ARMv7
7243            R[t] = bits(32) UNKNOWN;
7244#endif
7245
7246  bool success = false;
7247
7248  if (ConditionPassed(opcode)) {
7249    uint32_t t;
7250    uint32_t imm32;
7251    bool add;
7252
7253    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7254    switch (encoding) {
7255    case eEncodingT1:
7256      // if Rt == '1111' then SEE "Unallocated memory hints";
7257      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7258      t = Bits32(opcode, 15, 12);
7259      imm32 = Bits32(opcode, 11, 0);
7260      add = BitIsSet(opcode, 23);
7261
7262      // if t == 13 then UNPREDICTABLE;
7263      if (t == 13)
7264        return false;
7265
7266      break;
7267
7268    case eEncodingA1: {
7269      uint32_t imm4H = Bits32(opcode, 11, 8);
7270      uint32_t imm4L = Bits32(opcode, 3, 0);
7271
7272      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7273      t = Bits32(opcode, 15, 12);
7274      imm32 = (imm4H << 4) | imm4L;
7275      add = BitIsSet(opcode, 23);
7276
7277      // if t == 15 then UNPREDICTABLE;
7278      if (t == 15)
7279        return false;
7280      break;
7281    }
7282
7283    default:
7284      return false;
7285    }
7286
7287    // base = Align(PC,4);
7288    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7289    if (!success)
7290      return false;
7291
7292    addr_t base = AlignPC(pc_value);
7293    addr_t address;
7294
7295    // address = if add then (base + imm32) else (base - imm32);
7296    if (add)
7297      address = base + imm32;
7298    else
7299      address = base - imm32;
7300
7301    // data = MemU[address,2];
7302    RegisterInfo base_reg;
7303    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7304
7305    EmulateInstruction::Context context;
7306    context.type = eContextRegisterLoad;
7307    context.SetRegisterPlusOffset(base_reg, address - base);
7308
7309    uint64_t data = MemURead(context, address, 2, 0, &success);
7310    if (!success)
7311      return false;
7312
7313    // if UnalignedSupport() || address<0> = '0' then
7314    if (UnalignedSupport() || BitIsClear(address, 0)) {
7315      // R[t] = ZeroExtend(data, 32);
7316      context.type = eContextRegisterLoad;
7317      context.SetRegisterPlusOffset(base_reg, address - base);
7318      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7319                                 data))
7320        return false;
7321
7322    } else // Can only apply before ARMv7
7323    {
7324      // R[t] = bits(32) UNKNOWN;
7325      WriteBits32Unknown(t);
7326    }
7327  }
7328  return true;
7329}
7330
7331// LDRH (literal) calculates an address from a base register value and an offset
7332// register value, loads a halfword
7333// from memory, zero-extends it to form a 32-bit word, and writes it to a
7334// register.  The offset register value can be shifted left by 0, 1, 2, or 3
7335// bits.
7336bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
7337                                                const ARMEncoding encoding) {
7338#if 0
7339    if ConditionPassed() then
7340        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7341        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7342        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7343        address = if index then offset_addr else R[n];
7344        data = MemU[address,2];
7345        if wback then R[n] = offset_addr;
7346        if UnalignedSupport() || address<0> = '0' then
7347            R[t] = ZeroExtend(data, 32);
7348        else // Can only apply before ARMv7
7349            R[t] = bits(32) UNKNOWN;
7350#endif
7351
7352  bool success = false;
7353
7354  if (ConditionPassed(opcode)) {
7355    uint32_t t;
7356    uint32_t n;
7357    uint32_t m;
7358    bool index;
7359    bool add;
7360    bool wback;
7361    ARM_ShifterType shift_t;
7362    uint32_t shift_n;
7363
7364    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7365    switch (encoding) {
7366    case eEncodingT1:
7367      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7368      // in ThumbEE";
7369      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7370      t = Bits32(opcode, 2, 0);
7371      n = Bits32(opcode, 5, 3);
7372      m = Bits32(opcode, 8, 6);
7373
7374      // index = TRUE; add = TRUE; wback = FALSE;
7375      index = true;
7376      add = true;
7377      wback = false;
7378
7379      // (shift_t, shift_n) = (SRType_LSL, 0);
7380      shift_t = SRType_LSL;
7381      shift_n = 0;
7382
7383      break;
7384
7385    case eEncodingT2:
7386      // if Rn == '1111' then SEE LDRH (literal);
7387      // if Rt == '1111' then SEE "Unallocated memory hints";
7388      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7389      t = Bits32(opcode, 15, 12);
7390      n = Bits32(opcode, 19, 16);
7391      m = Bits32(opcode, 3, 0);
7392
7393      // index = TRUE; add = TRUE; wback = FALSE;
7394      index = true;
7395      add = true;
7396      wback = false;
7397
7398      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7399      shift_t = SRType_LSL;
7400      shift_n = Bits32(opcode, 5, 4);
7401
7402      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7403      if ((t == 13) || BadReg(m))
7404        return false;
7405      break;
7406
7407    case eEncodingA1:
7408      // if P == '0' && W == '1' then SEE LDRHT;
7409      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7410      t = Bits32(opcode, 15, 12);
7411      n = Bits32(opcode, 19, 16);
7412      m = Bits32(opcode, 3, 0);
7413
7414      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7415      // (W == '1');
7416      index = BitIsSet(opcode, 24);
7417      add = BitIsSet(opcode, 23);
7418      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7419
7420      // (shift_t, shift_n) = (SRType_LSL, 0);
7421      shift_t = SRType_LSL;
7422      shift_n = 0;
7423
7424      // if t == 15 || m == 15 then UNPREDICTABLE;
7425      if ((t == 15) || (m == 15))
7426        return false;
7427
7428      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7429      if (wback && ((n == 15) || (n == t)))
7430        return false;
7431
7432      break;
7433
7434    default:
7435      return false;
7436    }
7437
7438    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7439
7440    uint64_t Rm =
7441        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7442    if (!success)
7443      return false;
7444
7445    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7446    if (!success)
7447      return false;
7448
7449    addr_t offset_addr;
7450    addr_t address;
7451
7452    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7453    uint64_t Rn =
7454        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7455    if (!success)
7456      return false;
7457
7458    if (add)
7459      offset_addr = Rn + offset;
7460    else
7461      offset_addr = Rn - offset;
7462
7463    // address = if index then offset_addr else R[n];
7464    if (index)
7465      address = offset_addr;
7466    else
7467      address = Rn;
7468
7469    // data = MemU[address,2];
7470    RegisterInfo base_reg;
7471    RegisterInfo offset_reg;
7472    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7473    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7474
7475    EmulateInstruction::Context context;
7476    context.type = eContextRegisterLoad;
7477    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7478    uint64_t data = MemURead(context, address, 2, 0, &success);
7479    if (!success)
7480      return false;
7481
7482    // if wback then R[n] = offset_addr;
7483    if (wback) {
7484      context.type = eContextAdjustBaseRegister;
7485      context.SetAddress(offset_addr);
7486      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7487                                 offset_addr))
7488        return false;
7489    }
7490
7491    // if UnalignedSupport() || address<0> = '0' then
7492    if (UnalignedSupport() || BitIsClear(address, 0)) {
7493      // R[t] = ZeroExtend(data, 32);
7494      context.type = eContextRegisterLoad;
7495      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7496      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7497                                 data))
7498        return false;
7499    } else // Can only apply before ARMv7
7500    {
7501      // R[t] = bits(32) UNKNOWN;
7502      WriteBits32Unknown(t);
7503    }
7504  }
7505  return true;
7506}
7507
7508// LDRSB (immediate) calculates an address from a base register value and an
7509// immediate offset, loads a byte from
7510// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7511// It can use offset, post-indexed, or pre-indexed addressing.
7512bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7513                                                  const ARMEncoding encoding) {
7514#if 0
7515    if ConditionPassed() then
7516        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7517        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7518        address = if index then offset_addr else R[n];
7519        R[t] = SignExtend(MemU[address,1], 32);
7520        if wback then R[n] = offset_addr;
7521#endif
7522
7523  bool success = false;
7524
7525  if (ConditionPassed(opcode)) {
7526    uint32_t t;
7527    uint32_t n;
7528    uint32_t imm32;
7529    bool index;
7530    bool add;
7531    bool wback;
7532
7533    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7534    switch (encoding) {
7535    case eEncodingT1:
7536      // if Rt == '1111' then SEE PLI;
7537      // if Rn == '1111' then SEE LDRSB (literal);
7538      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7539      t = Bits32(opcode, 15, 12);
7540      n = Bits32(opcode, 19, 16);
7541      imm32 = Bits32(opcode, 11, 0);
7542
7543      // index = TRUE; add = TRUE; wback = FALSE;
7544      index = true;
7545      add = true;
7546      wback = false;
7547
7548      // if t == 13 then UNPREDICTABLE;
7549      if (t == 13)
7550        return false;
7551
7552      break;
7553
7554    case eEncodingT2:
7555      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7556      // if Rn == '1111' then SEE LDRSB (literal);
7557      // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7558      // if P == '0' && W == '0' then UNDEFINED;
7559      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7560        return false;
7561
7562      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7563      t = Bits32(opcode, 15, 12);
7564      n = Bits32(opcode, 19, 16);
7565      imm32 = Bits32(opcode, 7, 0);
7566
7567      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7568      index = BitIsSet(opcode, 10);
7569      add = BitIsSet(opcode, 9);
7570      wback = BitIsSet(opcode, 8);
7571
7572      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7573      if (((t == 13) ||
7574           ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7575                          BitIsSet(opcode, 8)))) ||
7576          (wback && (n == t)))
7577        return false;
7578
7579      break;
7580
7581    case eEncodingA1: {
7582      // if Rn == '1111' then SEE LDRSB (literal);
7583      // if P == '0' && W == '1' then SEE LDRSBT;
7584      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7585      t = Bits32(opcode, 15, 12);
7586      n = Bits32(opcode, 19, 16);
7587
7588      uint32_t imm4H = Bits32(opcode, 11, 8);
7589      uint32_t imm4L = Bits32(opcode, 3, 0);
7590      imm32 = (imm4H << 4) | imm4L;
7591
7592      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7593      // (W == '1');
7594      index = BitIsSet(opcode, 24);
7595      add = BitIsSet(opcode, 23);
7596      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7597
7598      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7599      if ((t == 15) || (wback && (n == t)))
7600        return false;
7601
7602      break;
7603    }
7604
7605    default:
7606      return false;
7607    }
7608
7609    uint64_t Rn = ReadCoreReg(n, &success);
7610    if (!success)
7611      return false;
7612
7613    addr_t offset_addr;
7614    addr_t address;
7615
7616    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7617    if (add)
7618      offset_addr = Rn + imm32;
7619    else
7620      offset_addr = Rn - imm32;
7621
7622    // address = if index then offset_addr else R[n];
7623    if (index)
7624      address = offset_addr;
7625    else
7626      address = Rn;
7627
7628    // R[t] = SignExtend(MemU[address,1], 32);
7629    RegisterInfo base_reg;
7630    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7631
7632    EmulateInstruction::Context context;
7633    context.type = eContextRegisterLoad;
7634    context.SetRegisterPlusOffset(base_reg, address - Rn);
7635
7636    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7637    if (!success)
7638      return false;
7639
7640    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7641    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7642                               (uint64_t)signed_data))
7643      return false;
7644
7645    // if wback then R[n] = offset_addr;
7646    if (wback) {
7647      context.type = eContextAdjustBaseRegister;
7648      context.SetAddress(offset_addr);
7649      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7650                                 offset_addr))
7651        return false;
7652    }
7653  }
7654
7655  return true;
7656}
7657
7658// LDRSB (literal) calculates an address from the PC value and an immediate
7659// offset, loads a byte from memory,
7660// sign-extends it to form a 32-bit word, and writes tit to a register.
7661bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7662                                                const ARMEncoding encoding) {
7663#if 0
7664    if ConditionPassed() then
7665        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7666        base = Align(PC,4);
7667        address = if add then (base + imm32) else (base - imm32);
7668        R[t] = SignExtend(MemU[address,1], 32);
7669#endif
7670
7671  bool success = false;
7672
7673  if (ConditionPassed(opcode)) {
7674    uint32_t t;
7675    uint32_t imm32;
7676    bool add;
7677
7678    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7679    switch (encoding) {
7680    case eEncodingT1:
7681      // if Rt == '1111' then SEE PLI;
7682      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7683      t = Bits32(opcode, 15, 12);
7684      imm32 = Bits32(opcode, 11, 0);
7685      add = BitIsSet(opcode, 23);
7686
7687      // if t == 13 then UNPREDICTABLE;
7688      if (t == 13)
7689        return false;
7690
7691      break;
7692
7693    case eEncodingA1: {
7694      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7695      t = Bits32(opcode, 15, 12);
7696      uint32_t imm4H = Bits32(opcode, 11, 8);
7697      uint32_t imm4L = Bits32(opcode, 3, 0);
7698      imm32 = (imm4H << 4) | imm4L;
7699      add = BitIsSet(opcode, 23);
7700
7701      // if t == 15 then UNPREDICTABLE;
7702      if (t == 15)
7703        return false;
7704
7705      break;
7706    }
7707
7708    default:
7709      return false;
7710    }
7711
7712    // base = Align(PC,4);
7713    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7714    if (!success)
7715      return false;
7716    uint64_t base = AlignPC(pc_value);
7717
7718    // address = if add then (base + imm32) else (base - imm32);
7719    addr_t address;
7720    if (add)
7721      address = base + imm32;
7722    else
7723      address = base - imm32;
7724
7725    // R[t] = SignExtend(MemU[address,1], 32);
7726    RegisterInfo base_reg;
7727    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7728
7729    EmulateInstruction::Context context;
7730    context.type = eContextRegisterLoad;
7731    context.SetRegisterPlusOffset(base_reg, address - base);
7732
7733    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7734    if (!success)
7735      return false;
7736
7737    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7738    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7739                               (uint64_t)signed_data))
7740      return false;
7741  }
7742  return true;
7743}
7744
7745// LDRSB (register) calculates an address from a base register value and an
7746// offset register value, loadsa byte from
7747// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7748// The offset register value can be shifted left by 0, 1, 2, or 3 bits.
7749bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7750                                                 const ARMEncoding encoding) {
7751#if 0
7752    if ConditionPassed() then
7753        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7754        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7755        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7756        address = if index then offset_addr else R[n];
7757        R[t] = SignExtend(MemU[address,1], 32);
7758        if wback then R[n] = offset_addr;
7759#endif
7760
7761  bool success = false;
7762
7763  if (ConditionPassed(opcode)) {
7764    uint32_t t;
7765    uint32_t n;
7766    uint32_t m;
7767    bool index;
7768    bool add;
7769    bool wback;
7770    ARM_ShifterType shift_t;
7771    uint32_t shift_n;
7772
7773    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7774    switch (encoding) {
7775    case eEncodingT1:
7776      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7777      t = Bits32(opcode, 2, 0);
7778      n = Bits32(opcode, 5, 3);
7779      m = Bits32(opcode, 8, 6);
7780
7781      // index = TRUE; add = TRUE; wback = FALSE;
7782      index = true;
7783      add = true;
7784      wback = false;
7785
7786      // (shift_t, shift_n) = (SRType_LSL, 0);
7787      shift_t = SRType_LSL;
7788      shift_n = 0;
7789
7790      break;
7791
7792    case eEncodingT2:
7793      // if Rt == '1111' then SEE PLI;
7794      // if Rn == '1111' then SEE LDRSB (literal);
7795      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7796      t = Bits32(opcode, 15, 12);
7797      n = Bits32(opcode, 19, 16);
7798      m = Bits32(opcode, 3, 0);
7799
7800      // index = TRUE; add = TRUE; wback = FALSE;
7801      index = true;
7802      add = true;
7803      wback = false;
7804
7805      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7806      shift_t = SRType_LSL;
7807      shift_n = Bits32(opcode, 5, 4);
7808
7809      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7810      if ((t == 13) || BadReg(m))
7811        return false;
7812      break;
7813
7814    case eEncodingA1:
7815      // if P == '0' && W == '1' then SEE LDRSBT;
7816      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7817      t = Bits32(opcode, 15, 12);
7818      n = Bits32(opcode, 19, 16);
7819      m = Bits32(opcode, 3, 0);
7820
7821      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7822      // (W == '1');
7823      index = BitIsSet(opcode, 24);
7824      add = BitIsSet(opcode, 23);
7825      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7826
7827      // (shift_t, shift_n) = (SRType_LSL, 0);
7828      shift_t = SRType_LSL;
7829      shift_n = 0;
7830
7831      // if t == 15 || m == 15 then UNPREDICTABLE;
7832      if ((t == 15) || (m == 15))
7833        return false;
7834
7835      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7836      if (wback && ((n == 15) || (n == t)))
7837        return false;
7838      break;
7839
7840    default:
7841      return false;
7842    }
7843
7844    uint64_t Rm =
7845        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7846    if (!success)
7847      return false;
7848
7849    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7850    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7851    if (!success)
7852      return false;
7853
7854    addr_t offset_addr;
7855    addr_t address;
7856
7857    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7858    uint64_t Rn =
7859        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7860    if (!success)
7861      return false;
7862
7863    if (add)
7864      offset_addr = Rn + offset;
7865    else
7866      offset_addr = Rn - offset;
7867
7868    // address = if index then offset_addr else R[n];
7869    if (index)
7870      address = offset_addr;
7871    else
7872      address = Rn;
7873
7874    // R[t] = SignExtend(MemU[address,1], 32);
7875    RegisterInfo base_reg;
7876    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7877    RegisterInfo offset_reg;
7878    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7879
7880    EmulateInstruction::Context context;
7881    context.type = eContextRegisterLoad;
7882    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7883
7884    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7885    if (!success)
7886      return false;
7887
7888    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7889    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7890                               (uint64_t)signed_data))
7891      return false;
7892
7893    // if wback then R[n] = offset_addr;
7894    if (wback) {
7895      context.type = eContextAdjustBaseRegister;
7896      context.SetAddress(offset_addr);
7897      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7898                                 offset_addr))
7899        return false;
7900    }
7901  }
7902  return true;
7903}
7904
7905// LDRSH (immediate) calculates an address from a base register value and an
7906// immediate offset, loads a halfword from
7907// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7908// It can use offset, post-indexed, or pre-indexed addressing.
7909bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7910                                                  const ARMEncoding encoding) {
7911#if 0
7912    if ConditionPassed() then
7913        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7914        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7915        address = if index then offset_addr else R[n];
7916        data = MemU[address,2];
7917        if wback then R[n] = offset_addr;
7918        if UnalignedSupport() || address<0> = '0' then
7919            R[t] = SignExtend(data, 32);
7920        else // Can only apply before ARMv7
7921            R[t] = bits(32) UNKNOWN;
7922#endif
7923
7924  bool success = false;
7925
7926  if (ConditionPassed(opcode)) {
7927    uint32_t t;
7928    uint32_t n;
7929    uint32_t imm32;
7930    bool index;
7931    bool add;
7932    bool wback;
7933
7934    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7935    switch (encoding) {
7936    case eEncodingT1:
7937      // if Rn == '1111' then SEE LDRSH (literal);
7938      // if Rt == '1111' then SEE "Unallocated memory hints";
7939      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7940      t = Bits32(opcode, 15, 12);
7941      n = Bits32(opcode, 19, 16);
7942      imm32 = Bits32(opcode, 11, 0);
7943
7944      // index = TRUE; add = TRUE; wback = FALSE;
7945      index = true;
7946      add = true;
7947      wback = false;
7948
7949      // if t == 13 then UNPREDICTABLE;
7950      if (t == 13)
7951        return false;
7952
7953      break;
7954
7955    case eEncodingT2:
7956      // if Rn == '1111' then SEE LDRSH (literal);
7957      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7958      // "Unallocated memory hints";
7959      // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7960      // if P == '0' && W == '0' then UNDEFINED;
7961      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7962        return false;
7963
7964      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7965      t = Bits32(opcode, 15, 12);
7966      n = Bits32(opcode, 19, 16);
7967      imm32 = Bits32(opcode, 7, 0);
7968
7969      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7970      index = BitIsSet(opcode, 10);
7971      add = BitIsSet(opcode, 9);
7972      wback = BitIsSet(opcode, 8);
7973
7974      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7975      if (BadReg(t) || (wback && (n == t)))
7976        return false;
7977
7978      break;
7979
7980    case eEncodingA1: {
7981      // if Rn == '1111' then SEE LDRSH (literal);
7982      // if P == '0' && W == '1' then SEE LDRSHT;
7983      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7984      t = Bits32(opcode, 15, 12);
7985      n = Bits32(opcode, 19, 16);
7986      uint32_t imm4H = Bits32(opcode, 11, 8);
7987      uint32_t imm4L = Bits32(opcode, 3, 0);
7988      imm32 = (imm4H << 4) | imm4L;
7989
7990      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
7991      // (W == '1');
7992      index = BitIsSet(opcode, 24);
7993      add = BitIsSet(opcode, 23);
7994      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7995
7996      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7997      if ((t == 15) || (wback && (n == t)))
7998        return false;
7999
8000      break;
8001    }
8002
8003    default:
8004      return false;
8005    }
8006
8007    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
8008    uint64_t Rn =
8009        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8010    if (!success)
8011      return false;
8012
8013    addr_t offset_addr;
8014    if (add)
8015      offset_addr = Rn + imm32;
8016    else
8017      offset_addr = Rn - imm32;
8018
8019    // address = if index then offset_addr else R[n];
8020    addr_t address;
8021    if (index)
8022      address = offset_addr;
8023    else
8024      address = Rn;
8025
8026    // data = MemU[address,2];
8027    RegisterInfo base_reg;
8028    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8029
8030    EmulateInstruction::Context context;
8031    context.type = eContextRegisterLoad;
8032    context.SetRegisterPlusOffset(base_reg, address - Rn);
8033
8034    uint64_t data = MemURead(context, address, 2, 0, &success);
8035    if (!success)
8036      return false;
8037
8038    // if wback then R[n] = offset_addr;
8039    if (wback) {
8040      context.type = eContextAdjustBaseRegister;
8041      context.SetAddress(offset_addr);
8042      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8043                                 offset_addr))
8044        return false;
8045    }
8046
8047    // if UnalignedSupport() || address<0> = '0' then
8048    if (UnalignedSupport() || BitIsClear(address, 0)) {
8049      // R[t] = SignExtend(data, 32);
8050      int64_t signed_data = llvm::SignExtend64<16>(data);
8051      context.type = eContextRegisterLoad;
8052      context.SetRegisterPlusOffset(base_reg, address - Rn);
8053      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8054                                 (uint64_t)signed_data))
8055        return false;
8056    } else // Can only apply before ARMv7
8057    {
8058      // R[t] = bits(32) UNKNOWN;
8059      WriteBits32Unknown(t);
8060    }
8061  }
8062  return true;
8063}
8064
8065// LDRSH (literal) calculates an address from the PC value and an immediate
8066// offset, loads a halfword from memory,
8067// sign-extends it to from a 32-bit word, and writes it to a register.
8068bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
8069                                                const ARMEncoding encoding) {
8070#if 0
8071    if ConditionPassed() then
8072        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8073        base = Align(PC,4);
8074        address = if add then (base + imm32) else (base - imm32);
8075        data = MemU[address,2];
8076        if UnalignedSupport() || address<0> = '0' then
8077            R[t] = SignExtend(data, 32);
8078        else // Can only apply before ARMv7
8079            R[t] = bits(32) UNKNOWN;
8080#endif
8081
8082  bool success = false;
8083
8084  if (ConditionPassed(opcode)) {
8085    uint32_t t;
8086    uint32_t imm32;
8087    bool add;
8088
8089    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
8090    switch (encoding) {
8091    case eEncodingT1:
8092      // if Rt == '1111' then SEE "Unallocated memory hints";
8093      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
8094      t = Bits32(opcode, 15, 12);
8095      imm32 = Bits32(opcode, 11, 0);
8096      add = BitIsSet(opcode, 23);
8097
8098      // if t == 13 then UNPREDICTABLE;
8099      if (t == 13)
8100        return false;
8101
8102      break;
8103
8104    case eEncodingA1: {
8105      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
8106      t = Bits32(opcode, 15, 12);
8107      uint32_t imm4H = Bits32(opcode, 11, 8);
8108      uint32_t imm4L = Bits32(opcode, 3, 0);
8109      imm32 = (imm4H << 4) | imm4L;
8110      add = BitIsSet(opcode, 23);
8111
8112      // if t == 15 then UNPREDICTABLE;
8113      if (t == 15)
8114        return false;
8115
8116      break;
8117    }
8118    default:
8119      return false;
8120    }
8121
8122    // base = Align(PC,4);
8123    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
8124    if (!success)
8125      return false;
8126
8127    uint64_t base = AlignPC(pc_value);
8128
8129    addr_t address;
8130    // address = if add then (base + imm32) else (base - imm32);
8131    if (add)
8132      address = base + imm32;
8133    else
8134      address = base - imm32;
8135
8136    // data = MemU[address,2];
8137    RegisterInfo base_reg;
8138    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
8139
8140    EmulateInstruction::Context context;
8141    context.type = eContextRegisterLoad;
8142    context.SetRegisterPlusOffset(base_reg, imm32);
8143
8144    uint64_t data = MemURead(context, address, 2, 0, &success);
8145    if (!success)
8146      return false;
8147
8148    // if UnalignedSupport() || address<0> = '0' then
8149    if (UnalignedSupport() || BitIsClear(address, 0)) {
8150      // R[t] = SignExtend(data, 32);
8151      int64_t signed_data = llvm::SignExtend64<16>(data);
8152      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8153                                 (uint64_t)signed_data))
8154        return false;
8155    } else // Can only apply before ARMv7
8156    {
8157      // R[t] = bits(32) UNKNOWN;
8158      WriteBits32Unknown(t);
8159    }
8160  }
8161  return true;
8162}
8163
8164// LDRSH (register) calculates an address from a base register value and an
8165// offset register value, loads a halfword
8166// from memory, sign-extends it to form a 32-bit word, and writes it to a
8167// register.  The offset register value can be shifted left by 0, 1, 2, or 3
8168// bits.
8169bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
8170                                                 const ARMEncoding encoding) {
8171#if 0
8172    if ConditionPassed() then
8173        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8174        offset = Shift(R[m], shift_t, shift_n, APSR.C);
8175        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8176        address = if index then offset_addr else R[n];
8177        data = MemU[address,2];
8178        if wback then R[n] = offset_addr;
8179        if UnalignedSupport() || address<0> = '0' then
8180            R[t] = SignExtend(data, 32);
8181        else // Can only apply before ARMv7
8182            R[t] = bits(32) UNKNOWN;
8183#endif
8184
8185  bool success = false;
8186
8187  if (ConditionPassed(opcode)) {
8188    uint32_t t;
8189    uint32_t n;
8190    uint32_t m;
8191    bool index;
8192    bool add;
8193    bool wback;
8194    ARM_ShifterType shift_t;
8195    uint32_t shift_n;
8196
8197    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
8198    switch (encoding) {
8199    case eEncodingT1:
8200      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
8201      // in ThumbEE";
8202      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8203      t = Bits32(opcode, 2, 0);
8204      n = Bits32(opcode, 5, 3);
8205      m = Bits32(opcode, 8, 6);
8206
8207      // index = TRUE; add = TRUE; wback = FALSE;
8208      index = true;
8209      add = true;
8210      wback = false;
8211
8212      // (shift_t, shift_n) = (SRType_LSL, 0);
8213      shift_t = SRType_LSL;
8214      shift_n = 0;
8215
8216      break;
8217
8218    case eEncodingT2:
8219      // if Rn == '1111' then SEE LDRSH (literal);
8220      // if Rt == '1111' then SEE "Unallocated memory hints";
8221      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8222      t = Bits32(opcode, 15, 12);
8223      n = Bits32(opcode, 19, 16);
8224      m = Bits32(opcode, 3, 0);
8225
8226      // index = TRUE; add = TRUE; wback = FALSE;
8227      index = true;
8228      add = true;
8229      wback = false;
8230
8231      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
8232      shift_t = SRType_LSL;
8233      shift_n = Bits32(opcode, 5, 4);
8234
8235      // if t == 13 || BadReg(m) then UNPREDICTABLE;
8236      if ((t == 13) || BadReg(m))
8237        return false;
8238
8239      break;
8240
8241    case eEncodingA1:
8242      // if P == '0' && W == '1' then SEE LDRSHT;
8243      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
8244      t = Bits32(opcode, 15, 12);
8245      n = Bits32(opcode, 19, 16);
8246      m = Bits32(opcode, 3, 0);
8247
8248      // index = (P == '1');     add = (U == '1');       wback = (P == '0') ||
8249      // (W == '1');
8250      index = BitIsSet(opcode, 24);
8251      add = BitIsSet(opcode, 23);
8252      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
8253
8254      // (shift_t, shift_n) = (SRType_LSL, 0);
8255      shift_t = SRType_LSL;
8256      shift_n = 0;
8257
8258      // if t == 15 || m == 15 then UNPREDICTABLE;
8259      if ((t == 15) || (m == 15))
8260        return false;
8261
8262      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
8263      if (wback && ((n == 15) || (n == t)))
8264        return false;
8265
8266      break;
8267
8268    default:
8269      return false;
8270    }
8271
8272    uint64_t Rm =
8273        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8274    if (!success)
8275      return false;
8276
8277    uint64_t Rn =
8278        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8279    if (!success)
8280      return false;
8281
8282    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
8283    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
8284    if (!success)
8285      return false;
8286
8287    addr_t offset_addr;
8288    addr_t address;
8289
8290    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
8291    if (add)
8292      offset_addr = Rn + offset;
8293    else
8294      offset_addr = Rn - offset;
8295
8296    // address = if index then offset_addr else R[n];
8297    if (index)
8298      address = offset_addr;
8299    else
8300      address = Rn;
8301
8302    // data = MemU[address,2];
8303    RegisterInfo base_reg;
8304    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8305
8306    RegisterInfo offset_reg;
8307    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
8308
8309    EmulateInstruction::Context context;
8310    context.type = eContextRegisterLoad;
8311    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8312
8313    uint64_t data = MemURead(context, address, 2, 0, &success);
8314    if (!success)
8315      return false;
8316
8317    // if wback then R[n] = offset_addr;
8318    if (wback) {
8319      context.type = eContextAdjustBaseRegister;
8320      context.SetAddress(offset_addr);
8321      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8322                                 offset_addr))
8323        return false;
8324    }
8325
8326    // if UnalignedSupport() || address<0> = '0' then
8327    if (UnalignedSupport() || BitIsClear(address, 0)) {
8328      // R[t] = SignExtend(data, 32);
8329      context.type = eContextRegisterLoad;
8330      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
8331
8332      int64_t signed_data = llvm::SignExtend64<16>(data);
8333      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
8334                                 (uint64_t)signed_data))
8335        return false;
8336    } else // Can only apply before ARMv7
8337    {
8338      // R[t] = bits(32) UNKNOWN;
8339      WriteBits32Unknown(t);
8340    }
8341  }
8342  return true;
8343}
8344
8345// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
8346// writes the result to the destination
8347// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
8348// extracting the 8-bit value.
8349bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
8350                                        const ARMEncoding encoding) {
8351#if 0
8352    if ConditionPassed() then
8353        EncodingSpecificOperations();
8354        rotated = ROR(R[m], rotation);
8355        R[d] = SignExtend(rotated<7:0>, 32);
8356#endif
8357
8358  bool success = false;
8359
8360  if (ConditionPassed(opcode)) {
8361    uint32_t d;
8362    uint32_t m;
8363    uint32_t rotation;
8364
8365    // EncodingSpecificOperations();
8366    switch (encoding) {
8367    case eEncodingT1:
8368      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8369      d = Bits32(opcode, 2, 0);
8370      m = Bits32(opcode, 5, 3);
8371      rotation = 0;
8372
8373      break;
8374
8375    case eEncodingT2:
8376      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8377      d = Bits32(opcode, 11, 8);
8378      m = Bits32(opcode, 3, 0);
8379      rotation = Bits32(opcode, 5, 4) << 3;
8380
8381      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8382      if (BadReg(d) || BadReg(m))
8383        return false;
8384
8385      break;
8386
8387    case eEncodingA1:
8388      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8389      d = Bits32(opcode, 15, 12);
8390      m = Bits32(opcode, 3, 0);
8391      rotation = Bits32(opcode, 11, 10) << 3;
8392
8393      // if d == 15 || m == 15 then UNPREDICTABLE;
8394      if ((d == 15) || (m == 15))
8395        return false;
8396
8397      break;
8398
8399    default:
8400      return false;
8401    }
8402
8403    uint64_t Rm =
8404        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8405    if (!success)
8406      return false;
8407
8408    // rotated = ROR(R[m], rotation);
8409    uint64_t rotated = ROR(Rm, rotation, &success);
8410    if (!success)
8411      return false;
8412
8413    // R[d] = SignExtend(rotated<7:0>, 32);
8414    int64_t data = llvm::SignExtend64<8>(rotated);
8415
8416    RegisterInfo source_reg;
8417    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8418
8419    EmulateInstruction::Context context;
8420    context.type = eContextRegisterLoad;
8421    context.SetRegister(source_reg);
8422
8423    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8424                               (uint64_t)data))
8425      return false;
8426  }
8427  return true;
8428}
8429
8430// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
8431// writes the result to the destination
8432// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8433// extracting the 16-bit value.
8434bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
8435                                        const ARMEncoding encoding) {
8436#if 0
8437    if ConditionPassed() then
8438        EncodingSpecificOperations();
8439        rotated = ROR(R[m], rotation);
8440        R[d] = SignExtend(rotated<15:0>, 32);
8441#endif
8442
8443  bool success = false;
8444
8445  if (ConditionPassed(opcode)) {
8446    uint32_t d;
8447    uint32_t m;
8448    uint32_t rotation;
8449
8450    // EncodingSpecificOperations();
8451    switch (encoding) {
8452    case eEncodingT1:
8453      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8454      d = Bits32(opcode, 2, 0);
8455      m = Bits32(opcode, 5, 3);
8456      rotation = 0;
8457
8458      break;
8459
8460    case eEncodingT2:
8461      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8462      d = Bits32(opcode, 11, 8);
8463      m = Bits32(opcode, 3, 0);
8464      rotation = Bits32(opcode, 5, 4) << 3;
8465
8466      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8467      if (BadReg(d) || BadReg(m))
8468        return false;
8469
8470      break;
8471
8472    case eEncodingA1:
8473      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8474      d = Bits32(opcode, 15, 12);
8475      m = Bits32(opcode, 3, 0);
8476      rotation = Bits32(opcode, 11, 10) << 3;
8477
8478      // if d == 15 || m == 15 then UNPREDICTABLE;
8479      if ((d == 15) || (m == 15))
8480        return false;
8481
8482      break;
8483
8484    default:
8485      return false;
8486    }
8487
8488    uint64_t Rm =
8489        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8490    if (!success)
8491      return false;
8492
8493    // rotated = ROR(R[m], rotation);
8494    uint64_t rotated = ROR(Rm, rotation, &success);
8495    if (!success)
8496      return false;
8497
8498    // R[d] = SignExtend(rotated<15:0>, 32);
8499    RegisterInfo source_reg;
8500    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8501
8502    EmulateInstruction::Context context;
8503    context.type = eContextRegisterLoad;
8504    context.SetRegister(source_reg);
8505
8506    int64_t data = llvm::SignExtend64<16>(rotated);
8507    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8508                               (uint64_t)data))
8509      return false;
8510  }
8511
8512  return true;
8513}
8514
8515// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
8516// writes the result to the destination
8517// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8518// extracting the 8-bit value.
8519bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8520                                        const ARMEncoding encoding) {
8521#if 0
8522    if ConditionPassed() then
8523        EncodingSpecificOperations();
8524        rotated = ROR(R[m], rotation);
8525        R[d] = ZeroExtend(rotated<7:0>, 32);
8526#endif
8527
8528  bool success = false;
8529
8530  if (ConditionPassed(opcode)) {
8531    uint32_t d;
8532    uint32_t m;
8533    uint32_t rotation;
8534
8535    // EncodingSpecificOperations();
8536    switch (encoding) {
8537    case eEncodingT1:
8538      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8539      d = Bits32(opcode, 2, 0);
8540      m = Bits32(opcode, 5, 3);
8541      rotation = 0;
8542
8543      break;
8544
8545    case eEncodingT2:
8546      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8547      d = Bits32(opcode, 11, 8);
8548      m = Bits32(opcode, 3, 0);
8549      rotation = Bits32(opcode, 5, 4) << 3;
8550
8551      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8552      if (BadReg(d) || BadReg(m))
8553        return false;
8554
8555      break;
8556
8557    case eEncodingA1:
8558      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8559      d = Bits32(opcode, 15, 12);
8560      m = Bits32(opcode, 3, 0);
8561      rotation = Bits32(opcode, 11, 10) << 3;
8562
8563      // if d == 15 || m == 15 then UNPREDICTABLE;
8564      if ((d == 15) || (m == 15))
8565        return false;
8566
8567      break;
8568
8569    default:
8570      return false;
8571    }
8572
8573    uint64_t Rm =
8574        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8575    if (!success)
8576      return false;
8577
8578    // rotated = ROR(R[m], rotation);
8579    uint64_t rotated = ROR(Rm, rotation, &success);
8580    if (!success)
8581      return false;
8582
8583    // R[d] = ZeroExtend(rotated<7:0>, 32);
8584    RegisterInfo source_reg;
8585    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8586
8587    EmulateInstruction::Context context;
8588    context.type = eContextRegisterLoad;
8589    context.SetRegister(source_reg);
8590
8591    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8592                               Bits32(rotated, 7, 0)))
8593      return false;
8594  }
8595  return true;
8596}
8597
8598// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8599// writes the result to the destination
8600// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8601// extracting the 16-bit value.
8602bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8603                                        const ARMEncoding encoding) {
8604#if 0
8605    if ConditionPassed() then
8606        EncodingSpecificOperations();
8607        rotated = ROR(R[m], rotation);
8608        R[d] = ZeroExtend(rotated<15:0>, 32);
8609#endif
8610
8611  bool success = false;
8612
8613  if (ConditionPassed(opcode)) {
8614    uint32_t d;
8615    uint32_t m;
8616    uint32_t rotation;
8617
8618    switch (encoding) {
8619    case eEncodingT1:
8620      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8621      d = Bits32(opcode, 2, 0);
8622      m = Bits32(opcode, 5, 3);
8623      rotation = 0;
8624
8625      break;
8626
8627    case eEncodingT2:
8628      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8629      d = Bits32(opcode, 11, 8);
8630      m = Bits32(opcode, 3, 0);
8631      rotation = Bits32(opcode, 5, 4) << 3;
8632
8633      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8634      if (BadReg(d) || BadReg(m))
8635        return false;
8636
8637      break;
8638
8639    case eEncodingA1:
8640      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8641      d = Bits32(opcode, 15, 12);
8642      m = Bits32(opcode, 3, 0);
8643      rotation = Bits32(opcode, 11, 10) << 3;
8644
8645      // if d == 15 || m == 15 then UNPREDICTABLE;
8646      if ((d == 15) || (m == 15))
8647        return false;
8648
8649      break;
8650
8651    default:
8652      return false;
8653    }
8654
8655    uint64_t Rm =
8656        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8657    if (!success)
8658      return false;
8659
8660    // rotated = ROR(R[m], rotation);
8661    uint64_t rotated = ROR(Rm, rotation, &success);
8662    if (!success)
8663      return false;
8664
8665    // R[d] = ZeroExtend(rotated<15:0>, 32);
8666    RegisterInfo source_reg;
8667    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8668
8669    EmulateInstruction::Context context;
8670    context.type = eContextRegisterLoad;
8671    context.SetRegister(source_reg);
8672
8673    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8674                               Bits32(rotated, 15, 0)))
8675      return false;
8676  }
8677  return true;
8678}
8679
8680// RFE (Return From Exception) loads the PC and the CPSR from the word at the
8681// specified address and the following
8682// word respectively.
8683bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8684                                       const ARMEncoding encoding) {
8685#if 0
8686    if ConditionPassed() then
8687        EncodingSpecificOperations();
8688        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8689            UNPREDICTABLE;
8690        else
8691            address = if increment then R[n] else R[n]-8;
8692            if wordhigher then address = address+4;
8693            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8694            BranchWritePC(MemA[address,4]);
8695            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8696#endif
8697
8698  bool success = false;
8699
8700  if (ConditionPassed(opcode)) {
8701    uint32_t n;
8702    bool wback;
8703    bool increment;
8704    bool wordhigher;
8705
8706    // EncodingSpecificOperations();
8707    switch (encoding) {
8708    case eEncodingT1:
8709      // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8710      // FALSE;
8711      n = Bits32(opcode, 19, 16);
8712      wback = BitIsSet(opcode, 21);
8713      increment = false;
8714      wordhigher = false;
8715
8716      // if n == 15 then UNPREDICTABLE;
8717      if (n == 15)
8718        return false;
8719
8720      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8721      if (InITBlock() && !LastInITBlock())
8722        return false;
8723
8724      break;
8725
8726    case eEncodingT2:
8727      // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8728      n = Bits32(opcode, 19, 16);
8729      wback = BitIsSet(opcode, 21);
8730      increment = true;
8731      wordhigher = false;
8732
8733      // if n == 15 then UNPREDICTABLE;
8734      if (n == 15)
8735        return false;
8736
8737      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8738      if (InITBlock() && !LastInITBlock())
8739        return false;
8740
8741      break;
8742
8743    case eEncodingA1:
8744      // n = UInt(Rn);
8745      n = Bits32(opcode, 19, 16);
8746
8747      // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8748      wback = BitIsSet(opcode, 21);
8749      increment = BitIsSet(opcode, 23);
8750      wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8751
8752      // if n == 15 then UNPREDICTABLE;
8753      if (n == 15)
8754        return false;
8755
8756      break;
8757
8758    default:
8759      return false;
8760    }
8761
8762    // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8763    // then
8764    if (!CurrentModeIsPrivileged())
8765      // UNPREDICTABLE;
8766      return false;
8767    else {
8768      uint64_t Rn =
8769          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8770      if (!success)
8771        return false;
8772
8773      addr_t address;
8774      // address = if increment then R[n] else R[n]-8;
8775      if (increment)
8776        address = Rn;
8777      else
8778        address = Rn - 8;
8779
8780      // if wordhigher then address = address+4;
8781      if (wordhigher)
8782        address = address + 4;
8783
8784      // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8785      RegisterInfo base_reg;
8786      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8787
8788      EmulateInstruction::Context context;
8789      context.type = eContextReturnFromException;
8790      context.SetRegisterPlusOffset(base_reg, address - Rn);
8791
8792      uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8793      if (!success)
8794        return false;
8795
8796      CPSRWriteByInstr(data, 15, true);
8797
8798      // BranchWritePC(MemA[address,4]);
8799      uint64_t data2 = MemARead(context, address, 4, 0, &success);
8800      if (!success)
8801        return false;
8802
8803      BranchWritePC(context, data2);
8804
8805      // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8806      if (wback) {
8807        context.type = eContextAdjustBaseRegister;
8808        if (increment) {
8809          context.SetOffset(8);
8810          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8811                                     Rn + 8))
8812            return false;
8813        } else {
8814          context.SetOffset(-8);
8815          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8816                                     Rn - 8))
8817            return false;
8818        }
8819      } // if wback
8820    }
8821  } // if ConditionPassed()
8822  return true;
8823}
8824
8825// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8826// register value and an immediate value, and writes the result to the
8827// destination register.  It can optionally update the condition flags based on
8828// the result.
8829bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8830                                          const ARMEncoding encoding) {
8831#if 0
8832    // ARM pseudo code...
8833    if ConditionPassed() then
8834        EncodingSpecificOperations();
8835        result = R[n] EOR imm32;
8836        if d == 15 then         // Can only occur for ARM encoding
8837            ALUWritePC(result); // setflags is always FALSE here
8838        else
8839            R[d] = result;
8840            if setflags then
8841                APSR.N = result<31>;
8842                APSR.Z = IsZeroBit(result);
8843                APSR.C = carry;
8844                // APSR.V unchanged
8845#endif
8846
8847  bool success = false;
8848
8849  if (ConditionPassed(opcode)) {
8850    uint32_t Rd, Rn;
8851    uint32_t
8852        imm32; // the immediate value to be ORed to the value obtained from Rn
8853    bool setflags;
8854    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8855    switch (encoding) {
8856    case eEncodingT1:
8857      Rd = Bits32(opcode, 11, 8);
8858      Rn = Bits32(opcode, 19, 16);
8859      setflags = BitIsSet(opcode, 20);
8860      imm32 = ThumbExpandImm_C(
8861          opcode, APSR_C,
8862          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8863      // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8864      if (Rd == 15 && setflags)
8865        return EmulateTEQImm(opcode, eEncodingT1);
8866      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8867        return false;
8868      break;
8869    case eEncodingA1:
8870      Rd = Bits32(opcode, 15, 12);
8871      Rn = Bits32(opcode, 19, 16);
8872      setflags = BitIsSet(opcode, 20);
8873      imm32 =
8874          ARMExpandImm_C(opcode, APSR_C,
8875                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8876
8877      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8878      // instructions;
8879      if (Rd == 15 && setflags)
8880        return EmulateSUBSPcLrEtc(opcode, encoding);
8881      break;
8882    default:
8883      return false;
8884    }
8885
8886    // Read the first operand.
8887    uint32_t val1 = ReadCoreReg(Rn, &success);
8888    if (!success)
8889      return false;
8890
8891    uint32_t result = val1 ^ imm32;
8892
8893    EmulateInstruction::Context context;
8894    context.type = EmulateInstruction::eContextImmediate;
8895    context.SetNoArgs();
8896
8897    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8898      return false;
8899  }
8900  return true;
8901}
8902
8903// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
8904// register value and an optionally-shifted register value, and writes the
8905// result to the destination register. It can optionally update the condition
8906// flags based on the result.
8907bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8908                                          const ARMEncoding encoding) {
8909#if 0
8910    // ARM pseudo code...
8911    if ConditionPassed() then
8912        EncodingSpecificOperations();
8913        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8914        result = R[n] EOR shifted;
8915        if d == 15 then         // Can only occur for ARM encoding
8916            ALUWritePC(result); // setflags is always FALSE here
8917        else
8918            R[d] = result;
8919            if setflags then
8920                APSR.N = result<31>;
8921                APSR.Z = IsZeroBit(result);
8922                APSR.C = carry;
8923                // APSR.V unchanged
8924#endif
8925
8926  bool success = false;
8927
8928  if (ConditionPassed(opcode)) {
8929    uint32_t Rd, Rn, Rm;
8930    ARM_ShifterType shift_t;
8931    uint32_t shift_n; // the shift applied to the value read from Rm
8932    bool setflags;
8933    uint32_t carry;
8934    switch (encoding) {
8935    case eEncodingT1:
8936      Rd = Rn = Bits32(opcode, 2, 0);
8937      Rm = Bits32(opcode, 5, 3);
8938      setflags = !InITBlock();
8939      shift_t = SRType_LSL;
8940      shift_n = 0;
8941      break;
8942    case eEncodingT2:
8943      Rd = Bits32(opcode, 11, 8);
8944      Rn = Bits32(opcode, 19, 16);
8945      Rm = Bits32(opcode, 3, 0);
8946      setflags = BitIsSet(opcode, 20);
8947      shift_n = DecodeImmShiftThumb(opcode, shift_t);
8948      // if Rd == '1111' && S == '1' then SEE TEQ (register);
8949      if (Rd == 15 && setflags)
8950        return EmulateTEQReg(opcode, eEncodingT1);
8951      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8952        return false;
8953      break;
8954    case eEncodingA1:
8955      Rd = Bits32(opcode, 15, 12);
8956      Rn = Bits32(opcode, 19, 16);
8957      Rm = Bits32(opcode, 3, 0);
8958      setflags = BitIsSet(opcode, 20);
8959      shift_n = DecodeImmShiftARM(opcode, shift_t);
8960
8961      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8962      // instructions;
8963      if (Rd == 15 && setflags)
8964        return EmulateSUBSPcLrEtc(opcode, encoding);
8965      break;
8966    default:
8967      return false;
8968    }
8969
8970    // Read the first operand.
8971    uint32_t val1 = ReadCoreReg(Rn, &success);
8972    if (!success)
8973      return false;
8974
8975    // Read the second operand.
8976    uint32_t val2 = ReadCoreReg(Rm, &success);
8977    if (!success)
8978      return false;
8979
8980    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8981    if (!success)
8982      return false;
8983    uint32_t result = val1 ^ shifted;
8984
8985    EmulateInstruction::Context context;
8986    context.type = EmulateInstruction::eContextImmediate;
8987    context.SetNoArgs();
8988
8989    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8990      return false;
8991  }
8992  return true;
8993}
8994
8995// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8996// and an immediate value, and writes the result to the destination register.
8997// It can optionally update the condition flags based on the result.
8998bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8999                                          const ARMEncoding encoding) {
9000#if 0
9001    // ARM pseudo code...
9002    if ConditionPassed() then
9003        EncodingSpecificOperations();
9004        result = R[n] OR imm32;
9005        if d == 15 then         // Can only occur for ARM encoding
9006            ALUWritePC(result); // setflags is always FALSE here
9007        else
9008            R[d] = result;
9009            if setflags then
9010                APSR.N = result<31>;
9011                APSR.Z = IsZeroBit(result);
9012                APSR.C = carry;
9013                // APSR.V unchanged
9014#endif
9015
9016  bool success = false;
9017
9018  if (ConditionPassed(opcode)) {
9019    uint32_t Rd, Rn;
9020    uint32_t
9021        imm32; // the immediate value to be ORed to the value obtained from Rn
9022    bool setflags;
9023    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9024    switch (encoding) {
9025    case eEncodingT1:
9026      Rd = Bits32(opcode, 11, 8);
9027      Rn = Bits32(opcode, 19, 16);
9028      setflags = BitIsSet(opcode, 20);
9029      imm32 = ThumbExpandImm_C(
9030          opcode, APSR_C,
9031          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9032      // if Rn == '1111' then SEE MOV (immediate);
9033      if (Rn == 15)
9034        return EmulateMOVRdImm(opcode, eEncodingT2);
9035      if (BadReg(Rd) || Rn == 13)
9036        return false;
9037      break;
9038    case eEncodingA1:
9039      Rd = Bits32(opcode, 15, 12);
9040      Rn = Bits32(opcode, 19, 16);
9041      setflags = BitIsSet(opcode, 20);
9042      imm32 =
9043          ARMExpandImm_C(opcode, APSR_C,
9044                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9045
9046      if (Rd == 15 && setflags)
9047        return EmulateSUBSPcLrEtc(opcode, encoding);
9048      break;
9049    default:
9050      return false;
9051    }
9052
9053    // Read the first operand.
9054    uint32_t val1 = ReadCoreReg(Rn, &success);
9055    if (!success)
9056      return false;
9057
9058    uint32_t result = val1 | imm32;
9059
9060    EmulateInstruction::Context context;
9061    context.type = EmulateInstruction::eContextImmediate;
9062    context.SetNoArgs();
9063
9064    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9065      return false;
9066  }
9067  return true;
9068}
9069
9070// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
9071// and an optionally-shifted register value, and writes the result to the
9072// destination register.  It can optionally update the condition flags based on
9073// the result.
9074bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
9075                                          const ARMEncoding encoding) {
9076#if 0
9077    // ARM pseudo code...
9078    if ConditionPassed() then
9079        EncodingSpecificOperations();
9080        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9081        result = R[n] OR shifted;
9082        if d == 15 then         // Can only occur for ARM encoding
9083            ALUWritePC(result); // setflags is always FALSE here
9084        else
9085            R[d] = result;
9086            if setflags then
9087                APSR.N = result<31>;
9088                APSR.Z = IsZeroBit(result);
9089                APSR.C = carry;
9090                // APSR.V unchanged
9091#endif
9092
9093  bool success = false;
9094
9095  if (ConditionPassed(opcode)) {
9096    uint32_t Rd, Rn, Rm;
9097    ARM_ShifterType shift_t;
9098    uint32_t shift_n; // the shift applied to the value read from Rm
9099    bool setflags;
9100    uint32_t carry;
9101    switch (encoding) {
9102    case eEncodingT1:
9103      Rd = Rn = Bits32(opcode, 2, 0);
9104      Rm = Bits32(opcode, 5, 3);
9105      setflags = !InITBlock();
9106      shift_t = SRType_LSL;
9107      shift_n = 0;
9108      break;
9109    case eEncodingT2:
9110      Rd = Bits32(opcode, 11, 8);
9111      Rn = Bits32(opcode, 19, 16);
9112      Rm = Bits32(opcode, 3, 0);
9113      setflags = BitIsSet(opcode, 20);
9114      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9115      // if Rn == '1111' then SEE MOV (register);
9116      if (Rn == 15)
9117        return EmulateMOVRdRm(opcode, eEncodingT3);
9118      if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
9119        return false;
9120      break;
9121    case eEncodingA1:
9122      Rd = Bits32(opcode, 15, 12);
9123      Rn = Bits32(opcode, 19, 16);
9124      Rm = Bits32(opcode, 3, 0);
9125      setflags = BitIsSet(opcode, 20);
9126      shift_n = DecodeImmShiftARM(opcode, shift_t);
9127
9128      if (Rd == 15 && setflags)
9129        return EmulateSUBSPcLrEtc(opcode, encoding);
9130      break;
9131    default:
9132      return false;
9133    }
9134
9135    // Read the first operand.
9136    uint32_t val1 = ReadCoreReg(Rn, &success);
9137    if (!success)
9138      return false;
9139
9140    // Read the second operand.
9141    uint32_t val2 = ReadCoreReg(Rm, &success);
9142    if (!success)
9143      return false;
9144
9145    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9146    if (!success)
9147      return false;
9148    uint32_t result = val1 | shifted;
9149
9150    EmulateInstruction::Context context;
9151    context.type = EmulateInstruction::eContextImmediate;
9152    context.SetNoArgs();
9153
9154    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
9155      return false;
9156  }
9157  return true;
9158}
9159
9160// Reverse Subtract (immediate) subtracts a register value from an immediate
9161// value, and writes the result to the destination register. It can optionally
9162// update the condition flags based on the result.
9163bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
9164                                          const ARMEncoding encoding) {
9165#if 0
9166    // ARM pseudo code...
9167    if ConditionPassed() then
9168        EncodingSpecificOperations();
9169        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
9170        if d == 15 then         // Can only occur for ARM encoding
9171            ALUWritePC(result); // setflags is always FALSE here
9172        else
9173            R[d] = result;
9174            if setflags then
9175                APSR.N = result<31>;
9176                APSR.Z = IsZeroBit(result);
9177                APSR.C = carry;
9178                APSR.V = overflow;
9179#endif
9180
9181  bool success = false;
9182
9183  uint32_t Rd; // the destination register
9184  uint32_t Rn; // the first operand
9185  bool setflags;
9186  uint32_t
9187      imm32; // the immediate value to be added to the value obtained from Rn
9188  switch (encoding) {
9189  case eEncodingT1:
9190    Rd = Bits32(opcode, 2, 0);
9191    Rn = Bits32(opcode, 5, 3);
9192    setflags = !InITBlock();
9193    imm32 = 0;
9194    break;
9195  case eEncodingT2:
9196    Rd = Bits32(opcode, 11, 8);
9197    Rn = Bits32(opcode, 19, 16);
9198    setflags = BitIsSet(opcode, 20);
9199    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9200    if (BadReg(Rd) || BadReg(Rn))
9201      return false;
9202    break;
9203  case eEncodingA1:
9204    Rd = Bits32(opcode, 15, 12);
9205    Rn = Bits32(opcode, 19, 16);
9206    setflags = BitIsSet(opcode, 20);
9207    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9208
9209    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9210    // instructions;
9211    if (Rd == 15 && setflags)
9212      return EmulateSUBSPcLrEtc(opcode, encoding);
9213    break;
9214  default:
9215    return false;
9216  }
9217  // Read the register value from the operand register Rn.
9218  uint32_t reg_val = ReadCoreReg(Rn, &success);
9219  if (!success)
9220    return false;
9221
9222  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
9223
9224  EmulateInstruction::Context context;
9225  context.type = EmulateInstruction::eContextImmediate;
9226  context.SetNoArgs();
9227
9228  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9229                                   res.carry_out, res.overflow);
9230}
9231
9232// Reverse Subtract (register) subtracts a register value from an optionally-
9233// shifted register value, and writes the result to the destination register.
9234// It can optionally update the condition flags based on the result.
9235bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
9236                                          const ARMEncoding encoding) {
9237#if 0
9238    // ARM pseudo code...
9239    if ConditionPassed() then
9240        EncodingSpecificOperations();
9241        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9242        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
9243        if d == 15 then         // Can only occur for ARM encoding
9244            ALUWritePC(result); // setflags is always FALSE here
9245        else
9246            R[d] = result;
9247            if setflags then
9248                APSR.N = result<31>;
9249                APSR.Z = IsZeroBit(result);
9250                APSR.C = carry;
9251                APSR.V = overflow;
9252#endif
9253
9254  bool success = false;
9255
9256  uint32_t Rd; // the destination register
9257  uint32_t Rn; // the first operand
9258  uint32_t Rm; // the second operand
9259  bool setflags;
9260  ARM_ShifterType shift_t;
9261  uint32_t shift_n; // the shift applied to the value read from Rm
9262  switch (encoding) {
9263  case eEncodingT1:
9264    Rd = Bits32(opcode, 11, 8);
9265    Rn = Bits32(opcode, 19, 16);
9266    Rm = Bits32(opcode, 3, 0);
9267    setflags = BitIsSet(opcode, 20);
9268    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9269    // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
9270    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9271      return false;
9272    break;
9273  case eEncodingA1:
9274    Rd = Bits32(opcode, 15, 12);
9275    Rn = Bits32(opcode, 19, 16);
9276    Rm = Bits32(opcode, 3, 0);
9277    setflags = BitIsSet(opcode, 20);
9278    shift_n = DecodeImmShiftARM(opcode, shift_t);
9279
9280    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9281    // instructions;
9282    if (Rd == 15 && setflags)
9283      return EmulateSUBSPcLrEtc(opcode, encoding);
9284    break;
9285  default:
9286    return false;
9287  }
9288  // Read the register value from register Rn.
9289  uint32_t val1 = ReadCoreReg(Rn, &success);
9290  if (!success)
9291    return false;
9292
9293  // Read the register value from register Rm.
9294  uint32_t val2 = ReadCoreReg(Rm, &success);
9295  if (!success)
9296    return false;
9297
9298  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9299  if (!success)
9300    return false;
9301  AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
9302
9303  EmulateInstruction::Context context;
9304  context.type = EmulateInstruction::eContextImmediate;
9305  context.SetNoArgs();
9306  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9307                                   res.carry_out, res.overflow);
9308}
9309
9310// Reverse Subtract with Carry (immediate) subtracts a register value and the
9311// value of NOT (Carry flag) from an immediate value, and writes the result to
9312// the destination register. It can optionally update the condition flags based
9313// on the result.
9314bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
9315                                          const ARMEncoding encoding) {
9316#if 0
9317    // ARM pseudo code...
9318    if ConditionPassed() then
9319        EncodingSpecificOperations();
9320        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
9321        if d == 15 then
9322            ALUWritePC(result); // setflags is always FALSE here
9323        else
9324            R[d] = result;
9325            if setflags then
9326                APSR.N = result<31>;
9327                APSR.Z = IsZeroBit(result);
9328                APSR.C = carry;
9329                APSR.V = overflow;
9330#endif
9331
9332  bool success = false;
9333
9334  uint32_t Rd; // the destination register
9335  uint32_t Rn; // the first operand
9336  bool setflags;
9337  uint32_t
9338      imm32; // the immediate value to be added to the value obtained from Rn
9339  switch (encoding) {
9340  case eEncodingA1:
9341    Rd = Bits32(opcode, 15, 12);
9342    Rn = Bits32(opcode, 19, 16);
9343    setflags = BitIsSet(opcode, 20);
9344    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
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 the operand register Rn.
9355  uint32_t reg_val = ReadCoreReg(Rn, &success);
9356  if (!success)
9357    return false;
9358
9359  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
9360
9361  EmulateInstruction::Context context;
9362  context.type = EmulateInstruction::eContextImmediate;
9363  context.SetNoArgs();
9364
9365  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9366                                   res.carry_out, res.overflow);
9367}
9368
9369// Reverse Subtract with Carry (register) subtracts a register value and the
9370// value of NOT (Carry flag) from an optionally-shifted register value, and
9371// writes the result to the destination register. It can optionally update the
9372// condition flags based on the result.
9373bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
9374                                          const ARMEncoding encoding) {
9375#if 0
9376    // ARM pseudo code...
9377    if ConditionPassed() then
9378        EncodingSpecificOperations();
9379        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9380        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
9381        if d == 15 then
9382            ALUWritePC(result); // setflags is always FALSE here
9383        else
9384            R[d] = result;
9385            if setflags then
9386                APSR.N = result<31>;
9387                APSR.Z = IsZeroBit(result);
9388                APSR.C = carry;
9389                APSR.V = overflow;
9390#endif
9391
9392  bool success = false;
9393
9394  uint32_t Rd; // the destination register
9395  uint32_t Rn; // the first operand
9396  uint32_t Rm; // the second operand
9397  bool setflags;
9398  ARM_ShifterType shift_t;
9399  uint32_t shift_n; // the shift applied to the value read from Rm
9400  switch (encoding) {
9401  case eEncodingA1:
9402    Rd = Bits32(opcode, 15, 12);
9403    Rn = Bits32(opcode, 19, 16);
9404    Rm = Bits32(opcode, 3, 0);
9405    setflags = BitIsSet(opcode, 20);
9406    shift_n = DecodeImmShiftARM(opcode, shift_t);
9407
9408    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9409    // instructions;
9410    if (Rd == 15 && setflags)
9411      return EmulateSUBSPcLrEtc(opcode, encoding);
9412    break;
9413  default:
9414    return false;
9415  }
9416  // Read the register value from register Rn.
9417  uint32_t val1 = ReadCoreReg(Rn, &success);
9418  if (!success)
9419    return false;
9420
9421  // Read the register value from register Rm.
9422  uint32_t val2 = ReadCoreReg(Rm, &success);
9423  if (!success)
9424    return false;
9425
9426  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9427  if (!success)
9428    return false;
9429  AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
9430
9431  EmulateInstruction::Context context;
9432  context.type = EmulateInstruction::eContextImmediate;
9433  context.SetNoArgs();
9434  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9435                                   res.carry_out, res.overflow);
9436}
9437
9438// Subtract with Carry (immediate) subtracts an immediate value and the value
9439// of
9440// NOT (Carry flag) from a register value, and writes the result to the
9441// destination register.
9442// It can optionally update the condition flags based on the result.
9443bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
9444                                          const ARMEncoding encoding) {
9445#if 0
9446    // ARM pseudo code...
9447    if ConditionPassed() then
9448        EncodingSpecificOperations();
9449        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9450        if d == 15 then         // Can only occur for ARM encoding
9451            ALUWritePC(result); // setflags is always FALSE here
9452        else
9453            R[d] = result;
9454            if setflags then
9455                APSR.N = result<31>;
9456                APSR.Z = IsZeroBit(result);
9457                APSR.C = carry;
9458                APSR.V = overflow;
9459#endif
9460
9461  bool success = false;
9462
9463  uint32_t Rd; // the destination register
9464  uint32_t Rn; // the first operand
9465  bool setflags;
9466  uint32_t
9467      imm32; // the immediate value to be added to the value obtained from Rn
9468  switch (encoding) {
9469  case eEncodingT1:
9470    Rd = Bits32(opcode, 11, 8);
9471    Rn = Bits32(opcode, 19, 16);
9472    setflags = BitIsSet(opcode, 20);
9473    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9474    if (BadReg(Rd) || BadReg(Rn))
9475      return false;
9476    break;
9477  case eEncodingA1:
9478    Rd = Bits32(opcode, 15, 12);
9479    Rn = Bits32(opcode, 19, 16);
9480    setflags = BitIsSet(opcode, 20);
9481    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9482
9483    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9484    // instructions;
9485    if (Rd == 15 && setflags)
9486      return EmulateSUBSPcLrEtc(opcode, encoding);
9487    break;
9488  default:
9489    return false;
9490  }
9491  // Read the register value from the operand register Rn.
9492  uint32_t reg_val = ReadCoreReg(Rn, &success);
9493  if (!success)
9494    return false;
9495
9496  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9497
9498  EmulateInstruction::Context context;
9499  context.type = EmulateInstruction::eContextImmediate;
9500  context.SetNoArgs();
9501
9502  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9503                                   res.carry_out, res.overflow);
9504}
9505
9506// Subtract with Carry (register) subtracts an optionally-shifted register
9507// value and the value of
9508// NOT (Carry flag) from a register value, and writes the result to the
9509// destination register.
9510// It can optionally update the condition flags based on the result.
9511bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9512                                          const ARMEncoding encoding) {
9513#if 0
9514    // ARM pseudo code...
9515    if ConditionPassed() then
9516        EncodingSpecificOperations();
9517        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9518        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9519        if d == 15 then         // Can only occur for ARM encoding
9520            ALUWritePC(result); // setflags is always FALSE here
9521        else
9522            R[d] = result;
9523            if setflags then
9524                APSR.N = result<31>;
9525                APSR.Z = IsZeroBit(result);
9526                APSR.C = carry;
9527                APSR.V = overflow;
9528#endif
9529
9530  bool success = false;
9531
9532  uint32_t Rd; // the destination register
9533  uint32_t Rn; // the first operand
9534  uint32_t Rm; // the second operand
9535  bool setflags;
9536  ARM_ShifterType shift_t;
9537  uint32_t shift_n; // the shift applied to the value read from Rm
9538  switch (encoding) {
9539  case eEncodingT1:
9540    Rd = Rn = Bits32(opcode, 2, 0);
9541    Rm = Bits32(opcode, 5, 3);
9542    setflags = !InITBlock();
9543    shift_t = SRType_LSL;
9544    shift_n = 0;
9545    break;
9546  case eEncodingT2:
9547    Rd = Bits32(opcode, 11, 8);
9548    Rn = Bits32(opcode, 19, 16);
9549    Rm = Bits32(opcode, 3, 0);
9550    setflags = BitIsSet(opcode, 20);
9551    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9552    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9553      return false;
9554    break;
9555  case eEncodingA1:
9556    Rd = Bits32(opcode, 15, 12);
9557    Rn = Bits32(opcode, 19, 16);
9558    Rm = Bits32(opcode, 3, 0);
9559    setflags = BitIsSet(opcode, 20);
9560    shift_n = DecodeImmShiftARM(opcode, shift_t);
9561
9562    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9563    // instructions;
9564    if (Rd == 15 && setflags)
9565      return EmulateSUBSPcLrEtc(opcode, encoding);
9566    break;
9567  default:
9568    return false;
9569  }
9570  // Read the register value from register Rn.
9571  uint32_t val1 = ReadCoreReg(Rn, &success);
9572  if (!success)
9573    return false;
9574
9575  // Read the register value from register Rm.
9576  uint32_t val2 = ReadCoreReg(Rm, &success);
9577  if (!success)
9578    return false;
9579
9580  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9581  if (!success)
9582    return false;
9583  AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9584
9585  EmulateInstruction::Context context;
9586  context.type = EmulateInstruction::eContextImmediate;
9587  context.SetNoArgs();
9588  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9589                                   res.carry_out, res.overflow);
9590}
9591
9592// This instruction subtracts an immediate value from a register value, and
9593// writes the result to the destination register.  It can optionally update the
9594// condition flags based on the result.
9595bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9596                                               const ARMEncoding encoding) {
9597#if 0
9598    // ARM pseudo code...
9599    if ConditionPassed() then
9600        EncodingSpecificOperations();
9601        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9602        R[d] = result;
9603        if setflags then
9604            APSR.N = result<31>;
9605            APSR.Z = IsZeroBit(result);
9606            APSR.C = carry;
9607            APSR.V = overflow;
9608#endif
9609
9610  bool success = false;
9611
9612  uint32_t Rd; // the destination register
9613  uint32_t Rn; // the first operand
9614  bool setflags;
9615  uint32_t imm32; // the immediate value to be subtracted from the value
9616                  // obtained from Rn
9617  switch (encoding) {
9618  case eEncodingT1:
9619    Rd = Bits32(opcode, 2, 0);
9620    Rn = Bits32(opcode, 5, 3);
9621    setflags = !InITBlock();
9622    imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9623    break;
9624  case eEncodingT2:
9625    Rd = Rn = Bits32(opcode, 10, 8);
9626    setflags = !InITBlock();
9627    imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9628    break;
9629  case eEncodingT3:
9630    Rd = Bits32(opcode, 11, 8);
9631    Rn = Bits32(opcode, 19, 16);
9632    setflags = BitIsSet(opcode, 20);
9633    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9634
9635    // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9636    if (Rd == 15 && setflags)
9637      return EmulateCMPImm(opcode, eEncodingT2);
9638
9639    // if Rn == '1101' then SEE SUB (SP minus immediate);
9640    if (Rn == 13)
9641      return EmulateSUBSPImm(opcode, eEncodingT2);
9642
9643    // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9644    if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9645      return false;
9646    break;
9647  case eEncodingT4:
9648    Rd = Bits32(opcode, 11, 8);
9649    Rn = Bits32(opcode, 19, 16);
9650    setflags = BitIsSet(opcode, 20);
9651    imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9652
9653    // if Rn == '1111' then SEE ADR;
9654    if (Rn == 15)
9655      return EmulateADR(opcode, eEncodingT2);
9656
9657    // if Rn == '1101' then SEE SUB (SP minus immediate);
9658    if (Rn == 13)
9659      return EmulateSUBSPImm(opcode, eEncodingT3);
9660
9661    if (BadReg(Rd))
9662      return false;
9663    break;
9664  default:
9665    return false;
9666  }
9667  // Read the register value from the operand register Rn.
9668  uint32_t reg_val = ReadCoreReg(Rn, &success);
9669  if (!success)
9670    return false;
9671
9672  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9673
9674  EmulateInstruction::Context context;
9675  context.type = EmulateInstruction::eContextImmediate;
9676  context.SetNoArgs();
9677
9678  return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9679                                   res.carry_out, res.overflow);
9680}
9681
9682// This instruction subtracts an immediate value from a register value, and
9683// writes the result to the destination register.  It can optionally update the
9684// condition flags based on the result.
9685bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9686                                             const ARMEncoding encoding) {
9687#if 0
9688    // ARM pseudo code...
9689    if ConditionPassed() then
9690        EncodingSpecificOperations();
9691        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9692        if d == 15 then
9693            ALUWritePC(result); // setflags is always FALSE here
9694        else
9695            R[d] = result;
9696            if setflags then
9697                APSR.N = result<31>;
9698                APSR.Z = IsZeroBit(result);
9699                APSR.C = carry;
9700                APSR.V = overflow;
9701#endif
9702
9703  bool success = false;
9704
9705  if (ConditionPassed(opcode)) {
9706    uint32_t Rd; // the destination register
9707    uint32_t Rn; // the first operand
9708    bool setflags;
9709    uint32_t imm32; // the immediate value to be subtracted from the value
9710                    // obtained from Rn
9711    switch (encoding) {
9712    case eEncodingA1:
9713      Rd = Bits32(opcode, 15, 12);
9714      Rn = Bits32(opcode, 19, 16);
9715      setflags = BitIsSet(opcode, 20);
9716      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9717
9718      // if Rn == '1111' && S == '0' then SEE ADR;
9719      if (Rn == 15 && !setflags)
9720        return EmulateADR(opcode, eEncodingA2);
9721
9722      // if Rn == '1101' then SEE SUB (SP minus immediate);
9723      if (Rn == 13)
9724        return EmulateSUBSPImm(opcode, eEncodingA1);
9725
9726      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9727      // instructions;
9728      if (Rd == 15 && setflags)
9729        return EmulateSUBSPcLrEtc(opcode, encoding);
9730      break;
9731    default:
9732      return false;
9733    }
9734    // Read the register value from the operand register Rn.
9735    uint32_t reg_val = ReadCoreReg(Rn, &success);
9736    if (!success)
9737      return false;
9738
9739    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9740
9741    EmulateInstruction::Context context;
9742    if (Rd == 13)
9743      context.type = EmulateInstruction::eContextAdjustStackPointer;
9744    else
9745      context.type = EmulateInstruction::eContextRegisterPlusOffset;
9746
9747    RegisterInfo dwarf_reg;
9748    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9749    int64_t imm32_signed = imm32;
9750    context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9751
9752    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9753                                   res.carry_out, res.overflow))
9754      return false;
9755  }
9756  return true;
9757}
9758
9759// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9760// register value and an immediate value.  It updates the condition flags based
9761// on the result, and discards the result.
9762bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9763                                          const ARMEncoding encoding) {
9764#if 0
9765    // ARM pseudo code...
9766    if ConditionPassed() then
9767        EncodingSpecificOperations();
9768        result = R[n] EOR imm32;
9769        APSR.N = result<31>;
9770        APSR.Z = IsZeroBit(result);
9771        APSR.C = carry;
9772        // APSR.V unchanged
9773#endif
9774
9775  bool success = false;
9776
9777  if (ConditionPassed(opcode)) {
9778    uint32_t Rn;
9779    uint32_t
9780        imm32; // the immediate value to be ANDed to the value obtained from Rn
9781    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9782    switch (encoding) {
9783    case eEncodingT1:
9784      Rn = Bits32(opcode, 19, 16);
9785      imm32 = ThumbExpandImm_C(
9786          opcode, APSR_C,
9787          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9788      if (BadReg(Rn))
9789        return false;
9790      break;
9791    case eEncodingA1:
9792      Rn = Bits32(opcode, 19, 16);
9793      imm32 =
9794          ARMExpandImm_C(opcode, APSR_C,
9795                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9796      break;
9797    default:
9798      return false;
9799    }
9800
9801    // Read the first operand.
9802    uint32_t val1 = ReadCoreReg(Rn, &success);
9803    if (!success)
9804      return false;
9805
9806    uint32_t result = val1 ^ imm32;
9807
9808    EmulateInstruction::Context context;
9809    context.type = EmulateInstruction::eContextImmediate;
9810    context.SetNoArgs();
9811
9812    if (!WriteFlags(context, result, carry))
9813      return false;
9814  }
9815  return true;
9816}
9817
9818// Test Equivalence (register) performs a bitwise exclusive OR operation on a
9819// register value and an optionally-shifted register value.  It updates the
9820// condition flags based on the result, and discards the result.
9821bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9822                                          const ARMEncoding encoding) {
9823#if 0
9824    // ARM pseudo code...
9825    if ConditionPassed() then
9826        EncodingSpecificOperations();
9827        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9828        result = R[n] EOR shifted;
9829        APSR.N = result<31>;
9830        APSR.Z = IsZeroBit(result);
9831        APSR.C = carry;
9832        // APSR.V unchanged
9833#endif
9834
9835  bool success = false;
9836
9837  if (ConditionPassed(opcode)) {
9838    uint32_t Rn, Rm;
9839    ARM_ShifterType shift_t;
9840    uint32_t shift_n; // the shift applied to the value read from Rm
9841    uint32_t carry;
9842    switch (encoding) {
9843    case eEncodingT1:
9844      Rn = Bits32(opcode, 19, 16);
9845      Rm = Bits32(opcode, 3, 0);
9846      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9847      if (BadReg(Rn) || BadReg(Rm))
9848        return false;
9849      break;
9850    case eEncodingA1:
9851      Rn = Bits32(opcode, 19, 16);
9852      Rm = Bits32(opcode, 3, 0);
9853      shift_n = DecodeImmShiftARM(opcode, shift_t);
9854      break;
9855    default:
9856      return false;
9857    }
9858
9859    // Read the first operand.
9860    uint32_t val1 = ReadCoreReg(Rn, &success);
9861    if (!success)
9862      return false;
9863
9864    // Read the second operand.
9865    uint32_t val2 = ReadCoreReg(Rm, &success);
9866    if (!success)
9867      return false;
9868
9869    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9870    if (!success)
9871      return false;
9872    uint32_t result = val1 ^ shifted;
9873
9874    EmulateInstruction::Context context;
9875    context.type = EmulateInstruction::eContextImmediate;
9876    context.SetNoArgs();
9877
9878    if (!WriteFlags(context, result, carry))
9879      return false;
9880  }
9881  return true;
9882}
9883
9884// Test (immediate) performs a bitwise AND operation on a register value and an
9885// immediate value. It updates the condition flags based on the result, and
9886// discards the result.
9887bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9888                                          const ARMEncoding encoding) {
9889#if 0
9890    // ARM pseudo code...
9891    if ConditionPassed() then
9892        EncodingSpecificOperations();
9893        result = R[n] AND imm32;
9894        APSR.N = result<31>;
9895        APSR.Z = IsZeroBit(result);
9896        APSR.C = carry;
9897        // APSR.V unchanged
9898#endif
9899
9900  bool success = false;
9901
9902  if (ConditionPassed(opcode)) {
9903    uint32_t Rn;
9904    uint32_t
9905        imm32; // the immediate value to be ANDed to the value obtained from Rn
9906    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9907    switch (encoding) {
9908    case eEncodingT1:
9909      Rn = Bits32(opcode, 19, 16);
9910      imm32 = ThumbExpandImm_C(
9911          opcode, APSR_C,
9912          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9913      if (BadReg(Rn))
9914        return false;
9915      break;
9916    case eEncodingA1:
9917      Rn = Bits32(opcode, 19, 16);
9918      imm32 =
9919          ARMExpandImm_C(opcode, APSR_C,
9920                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9921      break;
9922    default:
9923      return false;
9924    }
9925
9926    // Read the first operand.
9927    uint32_t val1 = ReadCoreReg(Rn, &success);
9928    if (!success)
9929      return false;
9930
9931    uint32_t result = val1 & imm32;
9932
9933    EmulateInstruction::Context context;
9934    context.type = EmulateInstruction::eContextImmediate;
9935    context.SetNoArgs();
9936
9937    if (!WriteFlags(context, result, carry))
9938      return false;
9939  }
9940  return true;
9941}
9942
9943// Test (register) performs a bitwise AND operation on a register value and an
9944// optionally-shifted register value. It updates the condition flags based on
9945// the result, and discards the result.
9946bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9947                                          const ARMEncoding encoding) {
9948#if 0
9949    // ARM pseudo code...
9950    if ConditionPassed() then
9951        EncodingSpecificOperations();
9952        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9953        result = R[n] AND shifted;
9954        APSR.N = result<31>;
9955        APSR.Z = IsZeroBit(result);
9956        APSR.C = carry;
9957        // APSR.V unchanged
9958#endif
9959
9960  bool success = false;
9961
9962  if (ConditionPassed(opcode)) {
9963    uint32_t Rn, Rm;
9964    ARM_ShifterType shift_t;
9965    uint32_t shift_n; // the shift applied to the value read from Rm
9966    uint32_t carry;
9967    switch (encoding) {
9968    case eEncodingT1:
9969      Rn = Bits32(opcode, 2, 0);
9970      Rm = Bits32(opcode, 5, 3);
9971      shift_t = SRType_LSL;
9972      shift_n = 0;
9973      break;
9974    case eEncodingT2:
9975      Rn = Bits32(opcode, 19, 16);
9976      Rm = Bits32(opcode, 3, 0);
9977      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9978      if (BadReg(Rn) || BadReg(Rm))
9979        return false;
9980      break;
9981    case eEncodingA1:
9982      Rn = Bits32(opcode, 19, 16);
9983      Rm = Bits32(opcode, 3, 0);
9984      shift_n = DecodeImmShiftARM(opcode, shift_t);
9985      break;
9986    default:
9987      return false;
9988    }
9989
9990    // Read the first operand.
9991    uint32_t val1 = ReadCoreReg(Rn, &success);
9992    if (!success)
9993      return false;
9994
9995    // Read the second operand.
9996    uint32_t val2 = ReadCoreReg(Rm, &success);
9997    if (!success)
9998      return false;
9999
10000    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
10001    if (!success)
10002      return false;
10003    uint32_t result = val1 & shifted;
10004
10005    EmulateInstruction::Context context;
10006    context.type = EmulateInstruction::eContextImmediate;
10007    context.SetNoArgs();
10008
10009    if (!WriteFlags(context, result, carry))
10010      return false;
10011  }
10012  return true;
10013}
10014
10015// A8.6.216 SUB (SP minus register)
10016bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
10017                                            const ARMEncoding encoding) {
10018#if 0
10019    if ConditionPassed() then
10020        EncodingSpecificOperations();
10021        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10022        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10023        if d == 15 then // Can only occur for ARM encoding
10024            ALUWritePC(result); // setflags is always FALSE here
10025        else
10026            R[d] = result;
10027            if setflags then
10028                APSR.N = result<31>;
10029                APSR.Z = IsZeroBit(result);
10030                APSR.C = carry;
10031                APSR.V = overflow;
10032#endif
10033
10034  bool success = false;
10035
10036  if (ConditionPassed(opcode)) {
10037    uint32_t d;
10038    uint32_t m;
10039    bool setflags;
10040    ARM_ShifterType shift_t;
10041    uint32_t shift_n;
10042
10043    switch (encoding) {
10044    case eEncodingT1:
10045      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10046      d = Bits32(opcode, 11, 8);
10047      m = Bits32(opcode, 3, 0);
10048      setflags = BitIsSet(opcode, 20);
10049
10050      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10051      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10052
10053      // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
10054      // UNPREDICTABLE;
10055      if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
10056        return false;
10057
10058      // if d == 15 || BadReg(m) then UNPREDICTABLE;
10059      if ((d == 15) || BadReg(m))
10060        return false;
10061      break;
10062
10063    case eEncodingA1:
10064      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
10065      d = Bits32(opcode, 15, 12);
10066      m = Bits32(opcode, 3, 0);
10067      setflags = BitIsSet(opcode, 20);
10068
10069      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10070      // instructions;
10071      if (d == 15 && setflags)
10072        EmulateSUBSPcLrEtc(opcode, encoding);
10073
10074      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10075      shift_n = DecodeImmShiftARM(opcode, shift_t);
10076      break;
10077
10078    default:
10079      return false;
10080    }
10081
10082    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10083    uint32_t Rm = ReadCoreReg(m, &success);
10084    if (!success)
10085      return false;
10086
10087    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10088    if (!success)
10089      return false;
10090
10091    // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
10092    uint32_t sp_val = ReadCoreReg(SP_REG, &success);
10093    if (!success)
10094      return false;
10095
10096    AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
10097
10098    EmulateInstruction::Context context;
10099    context.type = eContextArithmetic;
10100    RegisterInfo sp_reg;
10101    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
10102    RegisterInfo dwarf_reg;
10103    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
10104    context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
10105
10106    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10107                                   res.carry_out, res.overflow))
10108      return false;
10109  }
10110  return true;
10111}
10112
10113// A8.6.7 ADD (register-shifted register)
10114bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
10115                                               const ARMEncoding encoding) {
10116#if 0
10117    if ConditionPassed() then
10118        EncodingSpecificOperations();
10119        shift_n = UInt(R[s]<7:0>);
10120        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10121        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10122        R[d] = result;
10123        if setflags then
10124            APSR.N = result<31>;
10125            APSR.Z = IsZeroBit(result);
10126            APSR.C = carry;
10127            APSR.V = overflow;
10128#endif
10129
10130  bool success = false;
10131
10132  if (ConditionPassed(opcode)) {
10133    uint32_t d;
10134    uint32_t n;
10135    uint32_t m;
10136    uint32_t s;
10137    bool setflags;
10138    ARM_ShifterType shift_t;
10139
10140    switch (encoding) {
10141    case eEncodingA1:
10142      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
10143      d = Bits32(opcode, 15, 12);
10144      n = Bits32(opcode, 19, 16);
10145      m = Bits32(opcode, 3, 0);
10146      s = Bits32(opcode, 11, 8);
10147
10148      // setflags = (S == '1'); shift_t = DecodeRegShift(type);
10149      setflags = BitIsSet(opcode, 20);
10150      shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
10151
10152      // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
10153      if ((d == 15) || (n == 15) || (m == 15) || (s == 15))
10154        return false;
10155      break;
10156
10157    default:
10158      return false;
10159    }
10160
10161    // shift_n = UInt(R[s]<7:0>);
10162    uint32_t Rs = ReadCoreReg(s, &success);
10163    if (!success)
10164      return false;
10165
10166    uint32_t shift_n = Bits32(Rs, 7, 0);
10167
10168    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10169    uint32_t Rm = ReadCoreReg(m, &success);
10170    if (!success)
10171      return false;
10172
10173    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10174    if (!success)
10175      return false;
10176
10177    // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
10178    uint32_t Rn = ReadCoreReg(n, &success);
10179    if (!success)
10180      return false;
10181
10182    AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
10183
10184    // R[d] = result;
10185    EmulateInstruction::Context context;
10186    context.type = eContextArithmetic;
10187    RegisterInfo reg_n;
10188    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10189    RegisterInfo reg_m;
10190    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10191
10192    context.SetRegisterRegisterOperands(reg_n, reg_m);
10193
10194    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
10195                               res.result))
10196      return false;
10197
10198    // if setflags then
10199    // APSR.N = result<31>;
10200    // APSR.Z = IsZeroBit(result);
10201    // APSR.C = carry;
10202    // APSR.V = overflow;
10203    if (setflags)
10204      return WriteFlags(context, res.result, res.carry_out, res.overflow);
10205  }
10206  return true;
10207}
10208
10209// A8.6.213 SUB (register)
10210bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
10211                                          const ARMEncoding encoding) {
10212#if 0
10213    if ConditionPassed() then
10214        EncodingSpecificOperations();
10215        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10216        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10217        if d == 15 then // Can only occur for ARM encoding
10218            ALUWritePC(result); // setflags is always FALSE here
10219        else
10220            R[d] = result;
10221            if setflags then
10222                APSR.N = result<31>;
10223                APSR.Z = IsZeroBit(result);
10224                APSR.C = carry;
10225                APSR.V = overflow;
10226#endif
10227
10228  bool success = false;
10229
10230  if (ConditionPassed(opcode)) {
10231    uint32_t d;
10232    uint32_t n;
10233    uint32_t m;
10234    bool setflags;
10235    ARM_ShifterType shift_t;
10236    uint32_t shift_n;
10237
10238    switch (encoding) {
10239    case eEncodingT1:
10240      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
10241      d = Bits32(opcode, 2, 0);
10242      n = Bits32(opcode, 5, 3);
10243      m = Bits32(opcode, 8, 6);
10244      setflags = !InITBlock();
10245
10246      // (shift_t, shift_n) = (SRType_LSL, 0);
10247      shift_t = SRType_LSL;
10248      shift_n = 0;
10249
10250      break;
10251
10252    case eEncodingT2:
10253      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
10254      d = Bits32(opcode, 11, 8);
10255      n = Bits32(opcode, 19, 16);
10256      m = Bits32(opcode, 3, 0);
10257      setflags = BitIsSet(opcode, 20);
10258
10259      // if Rd == "1111" && S == "1" then SEE CMP (register);
10260      if (d == 15 && setflags == 1)
10261        return EmulateCMPImm(opcode, eEncodingT3);
10262
10263      // if Rn == "1101" then SEE SUB (SP minus register);
10264      if (n == 13)
10265        return EmulateSUBSPReg(opcode, eEncodingT1);
10266
10267      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
10268      shift_n = DecodeImmShiftThumb(opcode, shift_t);
10269
10270      // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
10271      // UNPREDICTABLE;
10272      if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
10273          BadReg(m))
10274        return false;
10275
10276      break;
10277
10278    case eEncodingA1:
10279      // if Rn == '1101' then SEE SUB (SP minus register);
10280      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
10281      d = Bits32(opcode, 15, 12);
10282      n = Bits32(opcode, 19, 16);
10283      m = Bits32(opcode, 3, 0);
10284      setflags = BitIsSet(opcode, 20);
10285
10286      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
10287      // instructions;
10288      if ((d == 15) && setflags)
10289        EmulateSUBSPcLrEtc(opcode, encoding);
10290
10291      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
10292      shift_n = DecodeImmShiftARM(opcode, shift_t);
10293
10294      break;
10295
10296    default:
10297      return false;
10298    }
10299
10300    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10301    uint32_t Rm = ReadCoreReg(m, &success);
10302    if (!success)
10303      return false;
10304
10305    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
10306    if (!success)
10307      return false;
10308
10309    // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
10310    uint32_t Rn = ReadCoreReg(n, &success);
10311    if (!success)
10312      return false;
10313
10314    AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
10315
10316    // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
10317    // // setflags is always FALSE here else
10318    // R[d] = result;
10319    // if setflags then
10320    // APSR.N = result<31>;
10321    // APSR.Z = IsZeroBit(result);
10322    // APSR.C = carry;
10323    // APSR.V = overflow;
10324
10325    EmulateInstruction::Context context;
10326    context.type = eContextArithmetic;
10327    RegisterInfo reg_n;
10328    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
10329    RegisterInfo reg_m;
10330    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
10331    context.SetRegisterRegisterOperands(reg_n, reg_m);
10332
10333    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
10334                                   res.carry_out, res.overflow))
10335      return false;
10336  }
10337  return true;
10338}
10339
10340// A8.6.202 STREX
10341// Store Register Exclusive calculates an address from a base register value
10342// and an immediate offset, and stores a word from a register to memory if the
10343// executing processor has exclusive access to the memory addressed.
10344bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
10345                                         const ARMEncoding encoding) {
10346#if 0
10347    if ConditionPassed() then
10348        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10349        address = R[n] + imm32;
10350        if ExclusiveMonitorsPass(address,4) then
10351            MemA[address,4] = R[t];
10352            R[d] = 0;
10353        else
10354            R[d] = 1;
10355#endif
10356
10357  bool success = false;
10358
10359  if (ConditionPassed(opcode)) {
10360    uint32_t d;
10361    uint32_t t;
10362    uint32_t n;
10363    uint32_t imm32;
10364    const uint32_t addr_byte_size = GetAddressByteSize();
10365
10366    switch (encoding) {
10367    case eEncodingT1:
10368      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
10369      // ZeroExtend(imm8:'00',
10370      // 32);
10371      d = Bits32(opcode, 11, 8);
10372      t = Bits32(opcode, 15, 12);
10373      n = Bits32(opcode, 19, 16);
10374      imm32 = Bits32(opcode, 7, 0) << 2;
10375
10376      // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
10377      if (BadReg(d) || BadReg(t) || (n == 15))
10378        return false;
10379
10380      // if d == n || d == t then UNPREDICTABLE;
10381      if ((d == n) || (d == t))
10382        return false;
10383
10384      break;
10385
10386    case eEncodingA1:
10387      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
10388      // offset
10389      d = Bits32(opcode, 15, 12);
10390      t = Bits32(opcode, 3, 0);
10391      n = Bits32(opcode, 19, 16);
10392      imm32 = 0;
10393
10394      // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
10395      if ((d == 15) || (t == 15) || (n == 15))
10396        return false;
10397
10398      // if d == n || d == t then UNPREDICTABLE;
10399      if ((d == n) || (d == t))
10400        return false;
10401
10402      break;
10403
10404    default:
10405      return false;
10406    }
10407
10408    // address = R[n] + imm32;
10409    uint32_t Rn = ReadCoreReg(n, &success);
10410    if (!success)
10411      return false;
10412
10413    addr_t address = Rn + imm32;
10414
10415    RegisterInfo base_reg;
10416    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10417    RegisterInfo data_reg;
10418    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10419    EmulateInstruction::Context context;
10420    context.type = eContextRegisterStore;
10421    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
10422
10423    // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
10424    // (address, addr_byte_size)) -- For now, for the sake of emulation, we
10425    // will say this
10426    //                                                         always return
10427    //                                                         true.
10428    if (true) {
10429      // MemA[address,4] = R[t];
10430      uint32_t Rt =
10431          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
10432      if (!success)
10433        return false;
10434
10435      if (!MemAWrite(context, address, Rt, addr_byte_size))
10436        return false;
10437
10438      // R[d] = 0;
10439      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
10440        return false;
10441    }
10442#if 0  // unreachable because if true
10443        else
10444        {
10445            // R[d] = 1;
10446            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10447                return false;
10448        }
10449#endif // unreachable because if true
10450  }
10451  return true;
10452}
10453
10454// A8.6.197 STRB (immediate, ARM)
10455bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
10456                                              const ARMEncoding encoding) {
10457#if 0
10458    if ConditionPassed() then
10459        EncodingSpecificOperations();
10460        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10461        address = if index then offset_addr else R[n];
10462        MemU[address,1] = R[t]<7:0>;
10463        if wback then R[n] = offset_addr;
10464#endif
10465
10466  bool success = false;
10467
10468  if (ConditionPassed(opcode)) {
10469    uint32_t t;
10470    uint32_t n;
10471    uint32_t imm32;
10472    bool index;
10473    bool add;
10474    bool wback;
10475
10476    switch (encoding) {
10477    case eEncodingA1:
10478      // if P == '0' && W == '1' then SEE STRBT;
10479      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10480      t = Bits32(opcode, 15, 12);
10481      n = Bits32(opcode, 19, 16);
10482      imm32 = Bits32(opcode, 11, 0);
10483
10484      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10485      index = BitIsSet(opcode, 24);
10486      add = BitIsSet(opcode, 23);
10487      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10488
10489      // if t == 15 then UNPREDICTABLE;
10490      if (t == 15)
10491        return false;
10492
10493      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10494      if (wback && ((n == 15) || (n == t)))
10495        return false;
10496
10497      break;
10498
10499    default:
10500      return false;
10501    }
10502
10503    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10504    uint32_t Rn = ReadCoreReg(n, &success);
10505    if (!success)
10506      return false;
10507
10508    addr_t offset_addr;
10509    if (add)
10510      offset_addr = Rn + imm32;
10511    else
10512      offset_addr = Rn - imm32;
10513
10514    // address = if index then offset_addr else R[n];
10515    addr_t address;
10516    if (index)
10517      address = offset_addr;
10518    else
10519      address = Rn;
10520
10521    // MemU[address,1] = R[t]<7:0>;
10522    uint32_t Rt = ReadCoreReg(t, &success);
10523    if (!success)
10524      return false;
10525
10526    RegisterInfo base_reg;
10527    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10528    RegisterInfo data_reg;
10529    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10530    EmulateInstruction::Context context;
10531    context.type = eContextRegisterStore;
10532    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10533
10534    if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10535      return false;
10536
10537    // if wback then R[n] = offset_addr;
10538    if (wback) {
10539      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10540                                 offset_addr))
10541        return false;
10542    }
10543  }
10544  return true;
10545}
10546
10547// A8.6.194 STR (immediate, ARM)
10548bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10549                                             const ARMEncoding encoding) {
10550#if 0
10551    if ConditionPassed() then
10552        EncodingSpecificOperations();
10553        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10554        address = if index then offset_addr else R[n];
10555        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10556        if wback then R[n] = offset_addr;
10557#endif
10558
10559  bool success = false;
10560
10561  if (ConditionPassed(opcode)) {
10562    uint32_t t;
10563    uint32_t n;
10564    uint32_t imm32;
10565    bool index;
10566    bool add;
10567    bool wback;
10568
10569    const uint32_t addr_byte_size = GetAddressByteSize();
10570
10571    switch (encoding) {
10572    case eEncodingA1:
10573      // if P == '0' && W == '1' then SEE STRT;
10574      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10575      // '000000000100' then SEE PUSH;
10576      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10577      t = Bits32(opcode, 15, 12);
10578      n = Bits32(opcode, 19, 16);
10579      imm32 = Bits32(opcode, 11, 0);
10580
10581      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10582      index = BitIsSet(opcode, 24);
10583      add = BitIsSet(opcode, 23);
10584      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10585
10586      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10587      if (wback && ((n == 15) || (n == t)))
10588        return false;
10589
10590      break;
10591
10592    default:
10593      return false;
10594    }
10595
10596    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10597    uint32_t Rn = ReadCoreReg(n, &success);
10598    if (!success)
10599      return false;
10600
10601    addr_t offset_addr;
10602    if (add)
10603      offset_addr = Rn + imm32;
10604    else
10605      offset_addr = Rn - imm32;
10606
10607    // address = if index then offset_addr else R[n];
10608    addr_t address;
10609    if (index)
10610      address = offset_addr;
10611    else
10612      address = Rn;
10613
10614    RegisterInfo base_reg;
10615    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10616    RegisterInfo data_reg;
10617    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10618    EmulateInstruction::Context context;
10619    context.type = eContextRegisterStore;
10620    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10621
10622    // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10623    uint32_t Rt = ReadCoreReg(t, &success);
10624    if (!success)
10625      return false;
10626
10627    if (t == 15) {
10628      uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10629      if (!success)
10630        return false;
10631
10632      if (!MemUWrite(context, address, pc_value, addr_byte_size))
10633        return false;
10634    } else {
10635      if (!MemUWrite(context, address, Rt, addr_byte_size))
10636        return false;
10637    }
10638
10639    // if wback then R[n] = offset_addr;
10640    if (wback) {
10641      context.type = eContextAdjustBaseRegister;
10642      context.SetImmediate(offset_addr);
10643
10644      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10645                                 offset_addr))
10646        return false;
10647    }
10648  }
10649  return true;
10650}
10651
10652// A8.6.66 LDRD (immediate)
10653// Load Register Dual (immediate) calculates an address from a base register
10654// value and an immediate offset, loads two words from memory, and writes them
10655// to two registers.  It can use offset, post-indexed, or pre-indexed
10656// addressing.
10657bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10658                                                 const ARMEncoding encoding) {
10659#if 0
10660    if ConditionPassed() then
10661        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10662        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10663        address = if index then offset_addr else R[n];
10664        R[t] = MemA[address,4];
10665        R[t2] = MemA[address+4,4];
10666        if wback then R[n] = offset_addr;
10667#endif
10668
10669  bool success = false;
10670
10671  if (ConditionPassed(opcode)) {
10672    uint32_t t;
10673    uint32_t t2;
10674    uint32_t n;
10675    uint32_t imm32;
10676    bool index;
10677    bool add;
10678    bool wback;
10679
10680    switch (encoding) {
10681    case eEncodingT1:
10682      // if P == '0' && W == '0' then SEE 'Related encodings';
10683      // if Rn == '1111' then SEE LDRD (literal);
10684      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10685      // ZeroExtend(imm8:'00', 32);
10686      t = Bits32(opcode, 15, 12);
10687      t2 = Bits32(opcode, 11, 8);
10688      n = Bits32(opcode, 19, 16);
10689      imm32 = Bits32(opcode, 7, 0) << 2;
10690
10691      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10692      index = BitIsSet(opcode, 24);
10693      add = BitIsSet(opcode, 23);
10694      wback = BitIsSet(opcode, 21);
10695
10696      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10697      if (wback && ((n == t) || (n == t2)))
10698        return false;
10699
10700      // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10701      if (BadReg(t) || BadReg(t2) || (t == t2))
10702        return false;
10703
10704      break;
10705
10706    case eEncodingA1:
10707      // if Rn == '1111' then SEE LDRD (literal);
10708      // if Rt<0> == '1' then UNPREDICTABLE;
10709      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10710      // 32);
10711      t = Bits32(opcode, 15, 12);
10712      if (BitIsSet(t, 0))
10713        return false;
10714      t2 = t + 1;
10715      n = Bits32(opcode, 19, 16);
10716      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10717
10718      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10719      index = BitIsSet(opcode, 24);
10720      add = BitIsSet(opcode, 23);
10721      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10722
10723      // if P == '0' && W == '1' then UNPREDICTABLE;
10724      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10725        return false;
10726
10727      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10728      if (wback && ((n == t) || (n == t2)))
10729        return false;
10730
10731      // if t2 == 15 then UNPREDICTABLE;
10732      if (t2 == 15)
10733        return false;
10734
10735      break;
10736
10737    default:
10738      return false;
10739    }
10740
10741    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10742    uint32_t Rn = ReadCoreReg(n, &success);
10743    if (!success)
10744      return false;
10745
10746    addr_t offset_addr;
10747    if (add)
10748      offset_addr = Rn + imm32;
10749    else
10750      offset_addr = Rn - imm32;
10751
10752    // address = if index then offset_addr else R[n];
10753    addr_t address;
10754    if (index)
10755      address = offset_addr;
10756    else
10757      address = Rn;
10758
10759    // R[t] = MemA[address,4];
10760    RegisterInfo base_reg;
10761    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10762
10763    EmulateInstruction::Context context;
10764    if (n == 13)
10765      context.type = eContextPopRegisterOffStack;
10766    else
10767      context.type = eContextRegisterLoad;
10768    context.SetAddress(address);
10769
10770    const uint32_t addr_byte_size = GetAddressByteSize();
10771    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10772    if (!success)
10773      return false;
10774
10775    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10776      return false;
10777
10778    // R[t2] = MemA[address+4,4];
10779    context.SetAddress(address + 4);
10780    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10781    if (!success)
10782      return false;
10783
10784    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10785                               data))
10786      return false;
10787
10788    // if wback then R[n] = offset_addr;
10789    if (wback) {
10790      context.type = eContextAdjustBaseRegister;
10791      context.SetAddress(offset_addr);
10792
10793      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10794                                 offset_addr))
10795        return false;
10796    }
10797  }
10798  return true;
10799}
10800
10801// A8.6.68 LDRD (register)
10802// Load Register Dual (register) calculates an address from a base register
10803// value and a register offset, loads two words from memory, and writes them to
10804// two registers.  It can use offset, post-indexed or pre-indexed addressing.
10805bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10806                                                const ARMEncoding encoding) {
10807#if 0
10808    if ConditionPassed() then
10809        EncodingSpecificOperations();
10810        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10811        address = if index then offset_addr else R[n];
10812        R[t] = MemA[address,4];
10813        R[t2] = MemA[address+4,4];
10814        if wback then R[n] = offset_addr;
10815#endif
10816
10817  bool success = false;
10818
10819  if (ConditionPassed(opcode)) {
10820    uint32_t t;
10821    uint32_t t2;
10822    uint32_t n;
10823    uint32_t m;
10824    bool index;
10825    bool add;
10826    bool wback;
10827
10828    switch (encoding) {
10829    case eEncodingA1:
10830      // if Rt<0> == '1' then UNPREDICTABLE;
10831      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10832      t = Bits32(opcode, 15, 12);
10833      if (BitIsSet(t, 0))
10834        return false;
10835      t2 = t + 1;
10836      n = Bits32(opcode, 19, 16);
10837      m = Bits32(opcode, 3, 0);
10838
10839      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10840      index = BitIsSet(opcode, 24);
10841      add = BitIsSet(opcode, 23);
10842      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10843
10844      // if P == '0' && W == '1' then UNPREDICTABLE;
10845      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10846        return false;
10847
10848      // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10849      if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10850        return false;
10851
10852      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10853      if (wback && ((n == 15) || (n == t) || (n == t2)))
10854        return false;
10855
10856      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10857      if ((ArchVersion() < 6) && wback && (m == n))
10858        return false;
10859      break;
10860
10861    default:
10862      return false;
10863    }
10864
10865    uint32_t Rn = ReadCoreReg(n, &success);
10866    if (!success)
10867      return false;
10868    RegisterInfo base_reg;
10869    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10870
10871    uint32_t Rm = ReadCoreReg(m, &success);
10872    if (!success)
10873      return false;
10874    RegisterInfo offset_reg;
10875    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10876
10877    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10878    addr_t offset_addr;
10879    if (add)
10880      offset_addr = Rn + Rm;
10881    else
10882      offset_addr = Rn - Rm;
10883
10884    // address = if index then offset_addr else R[n];
10885    addr_t address;
10886    if (index)
10887      address = offset_addr;
10888    else
10889      address = Rn;
10890
10891    EmulateInstruction::Context context;
10892    if (n == 13)
10893      context.type = eContextPopRegisterOffStack;
10894    else
10895      context.type = eContextRegisterLoad;
10896    context.SetAddress(address);
10897
10898    // R[t] = MemA[address,4];
10899    const uint32_t addr_byte_size = GetAddressByteSize();
10900    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10901    if (!success)
10902      return false;
10903
10904    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10905      return false;
10906
10907    // R[t2] = MemA[address+4,4];
10908
10909    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10910    if (!success)
10911      return false;
10912
10913    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10914                               data))
10915      return false;
10916
10917    // if wback then R[n] = offset_addr;
10918    if (wback) {
10919      context.type = eContextAdjustBaseRegister;
10920      context.SetAddress(offset_addr);
10921
10922      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10923                                 offset_addr))
10924        return false;
10925    }
10926  }
10927  return true;
10928}
10929
10930// A8.6.200 STRD (immediate)
10931// Store Register Dual (immediate) calculates an address from a base register
10932// value and an immediate offset, and stores two words from two registers to
10933// memory.  It can use offset, post-indexed, or pre-indexed addressing.
10934bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10935                                           const ARMEncoding encoding) {
10936#if 0
10937    if ConditionPassed() then
10938        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10939        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10940        address = if index then offset_addr else R[n];
10941        MemA[address,4] = R[t];
10942        MemA[address+4,4] = R[t2];
10943        if wback then R[n] = offset_addr;
10944#endif
10945
10946  bool success = false;
10947
10948  if (ConditionPassed(opcode)) {
10949    uint32_t t;
10950    uint32_t t2;
10951    uint32_t n;
10952    uint32_t imm32;
10953    bool index;
10954    bool add;
10955    bool wback;
10956
10957    switch (encoding) {
10958    case eEncodingT1:
10959      // if P == '0' && W == '0' then SEE 'Related encodings';
10960      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10961      // ZeroExtend(imm8:'00', 32);
10962      t = Bits32(opcode, 15, 12);
10963      t2 = Bits32(opcode, 11, 8);
10964      n = Bits32(opcode, 19, 16);
10965      imm32 = Bits32(opcode, 7, 0) << 2;
10966
10967      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10968      index = BitIsSet(opcode, 24);
10969      add = BitIsSet(opcode, 23);
10970      wback = BitIsSet(opcode, 21);
10971
10972      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10973      if (wback && ((n == t) || (n == t2)))
10974        return false;
10975
10976      // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10977      if ((n == 15) || BadReg(t) || BadReg(t2))
10978        return false;
10979
10980      break;
10981
10982    case eEncodingA1:
10983      // if Rt<0> == '1' then UNPREDICTABLE;
10984      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10985      // 32);
10986      t = Bits32(opcode, 15, 12);
10987      if (BitIsSet(t, 0))
10988        return false;
10989
10990      t2 = t + 1;
10991      n = Bits32(opcode, 19, 16);
10992      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10993
10994      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10995      index = BitIsSet(opcode, 24);
10996      add = BitIsSet(opcode, 23);
10997      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10998
10999      // if P == '0' && W == '1' then UNPREDICTABLE;
11000      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11001        return false;
11002
11003      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11004      if (wback && ((n == 15) || (n == t) || (n == t2)))
11005        return false;
11006
11007      // if t2 == 15 then UNPREDICTABLE;
11008      if (t2 == 15)
11009        return false;
11010
11011      break;
11012
11013    default:
11014      return false;
11015    }
11016
11017    RegisterInfo base_reg;
11018    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11019
11020    uint32_t Rn = ReadCoreReg(n, &success);
11021    if (!success)
11022      return false;
11023
11024    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
11025    addr_t offset_addr;
11026    if (add)
11027      offset_addr = Rn + imm32;
11028    else
11029      offset_addr = Rn - imm32;
11030
11031    // address = if index then offset_addr else R[n];
11032    addr_t address;
11033    if (index)
11034      address = offset_addr;
11035    else
11036      address = Rn;
11037
11038    // MemA[address,4] = R[t];
11039    RegisterInfo data_reg;
11040    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11041
11042    uint32_t data = ReadCoreReg(t, &success);
11043    if (!success)
11044      return false;
11045
11046    EmulateInstruction::Context context;
11047    if (n == 13)
11048      context.type = eContextPushRegisterOnStack;
11049    else
11050      context.type = eContextRegisterStore;
11051    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11052
11053    const uint32_t addr_byte_size = GetAddressByteSize();
11054
11055    if (!MemAWrite(context, address, data, addr_byte_size))
11056      return false;
11057
11058    // MemA[address+4,4] = R[t2];
11059    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11060    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11061                                            (address + 4) - Rn);
11062
11063    data = ReadCoreReg(t2, &success);
11064    if (!success)
11065      return false;
11066
11067    if (!MemAWrite(context, address + 4, data, addr_byte_size))
11068      return false;
11069
11070    // if wback then R[n] = offset_addr;
11071    if (wback) {
11072      if (n == 13)
11073        context.type = eContextAdjustStackPointer;
11074      else
11075        context.type = eContextAdjustBaseRegister;
11076      context.SetAddress(offset_addr);
11077
11078      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11079                                 offset_addr))
11080        return false;
11081    }
11082  }
11083  return true;
11084}
11085
11086// A8.6.201 STRD (register)
11087bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
11088                                           const ARMEncoding encoding) {
11089#if 0
11090    if ConditionPassed() then
11091        EncodingSpecificOperations();
11092        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11093        address = if index then offset_addr else R[n];
11094        MemA[address,4] = R[t];
11095        MemA[address+4,4] = R[t2];
11096        if wback then R[n] = offset_addr;
11097#endif
11098
11099  bool success = false;
11100
11101  if (ConditionPassed(opcode)) {
11102    uint32_t t;
11103    uint32_t t2;
11104    uint32_t n;
11105    uint32_t m;
11106    bool index;
11107    bool add;
11108    bool wback;
11109
11110    switch (encoding) {
11111    case eEncodingA1:
11112      // if Rt<0> == '1' then UNPREDICTABLE;
11113      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
11114      t = Bits32(opcode, 15, 12);
11115      if (BitIsSet(t, 0))
11116        return false;
11117
11118      t2 = t + 1;
11119      n = Bits32(opcode, 19, 16);
11120      m = Bits32(opcode, 3, 0);
11121
11122      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
11123      index = BitIsSet(opcode, 24);
11124      add = BitIsSet(opcode, 23);
11125      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
11126
11127      // if P == '0' && W == '1' then UNPREDICTABLE;
11128      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
11129        return false;
11130
11131      // if t2 == 15 || m == 15 then UNPREDICTABLE;
11132      if ((t2 == 15) || (m == 15))
11133        return false;
11134
11135      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
11136      if (wback && ((n == 15) || (n == t) || (n == t2)))
11137        return false;
11138
11139      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
11140      if ((ArchVersion() < 6) && wback && (m == n))
11141        return false;
11142
11143      break;
11144
11145    default:
11146      return false;
11147    }
11148
11149    RegisterInfo base_reg;
11150    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11151    RegisterInfo offset_reg;
11152    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
11153    RegisterInfo data_reg;
11154
11155    uint32_t Rn = ReadCoreReg(n, &success);
11156    if (!success)
11157      return false;
11158
11159    uint32_t Rm = ReadCoreReg(m, &success);
11160    if (!success)
11161      return false;
11162
11163    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
11164    addr_t offset_addr;
11165    if (add)
11166      offset_addr = Rn + Rm;
11167    else
11168      offset_addr = Rn - Rm;
11169
11170    // address = if index then offset_addr else R[n];
11171    addr_t address;
11172    if (index)
11173      address = offset_addr;
11174    else
11175      address = Rn;
11176    // MemA[address,4] = R[t];
11177    uint32_t Rt = ReadCoreReg(t, &success);
11178    if (!success)
11179      return false;
11180
11181    EmulateInstruction::Context context;
11182    if (t == 13)
11183      context.type = eContextPushRegisterOnStack;
11184    else
11185      context.type = eContextRegisterStore;
11186
11187    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
11188    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11189                                                    data_reg);
11190
11191    const uint32_t addr_byte_size = GetAddressByteSize();
11192
11193    if (!MemAWrite(context, address, Rt, addr_byte_size))
11194      return false;
11195
11196    // MemA[address+4,4] = R[t2];
11197    uint32_t Rt2 = ReadCoreReg(t2, &success);
11198    if (!success)
11199      return false;
11200
11201    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
11202
11203    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
11204                                                    data_reg);
11205
11206    if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
11207      return false;
11208
11209    // if wback then R[n] = offset_addr;
11210    if (wback) {
11211      context.type = eContextAdjustBaseRegister;
11212      context.SetAddress(offset_addr);
11213
11214      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11215                                 offset_addr))
11216        return false;
11217    }
11218  }
11219  return true;
11220}
11221
11222// A8.6.319 VLDM
11223// Vector Load Multiple loads multiple extension registers from consecutive
11224// memory locations using an address from an ARM core register.
11225bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
11226                                        const ARMEncoding encoding) {
11227#if 0
11228    if ConditionPassed() then
11229        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11230        address = if add then R[n] else R[n]-imm32;
11231        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11232        for r = 0 to regs-1
11233            if single_regs then
11234                S[d+r] = MemA[address,4]; address = address+4;
11235            else
11236                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
11237                // Combine the word-aligned words in the correct order for
11238                // current endianness.
11239                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11240#endif
11241
11242  bool success = false;
11243
11244  if (ConditionPassed(opcode)) {
11245    bool single_regs;
11246    bool add;
11247    bool wback;
11248    uint32_t d;
11249    uint32_t n;
11250    uint32_t imm32;
11251    uint32_t regs;
11252
11253    switch (encoding) {
11254    case eEncodingT1:
11255    case eEncodingA1:
11256      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11257      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11258      // if P == '1' && W == '0' then SEE VLDR;
11259      // if P == U && W == '1' then UNDEFINED;
11260      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11261        return false;
11262
11263      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11264      // !), 101 (DB with !)
11265      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11266      single_regs = false;
11267      add = BitIsSet(opcode, 23);
11268      wback = BitIsSet(opcode, 21);
11269
11270      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11271      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11272      n = Bits32(opcode, 19, 16);
11273      imm32 = Bits32(opcode, 7, 0) << 2;
11274
11275      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
11276      regs = Bits32(opcode, 7, 0) / 2;
11277
11278      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11279      // UNPREDICTABLE;
11280      if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
11281        return false;
11282
11283      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11284      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11285        return false;
11286
11287      break;
11288
11289    case eEncodingT2:
11290    case eEncodingA2:
11291      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11292      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
11293      // if P == '1' && W == '0' then SEE VLDR;
11294      // if P == U && W == '1' then UNDEFINED;
11295      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11296        return false;
11297
11298      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11299      // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11300      // == '1'); d =
11301      // UInt(Vd:D); n = UInt(Rn);
11302      single_regs = true;
11303      add = BitIsSet(opcode, 23);
11304      wback = BitIsSet(opcode, 21);
11305      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11306      n = Bits32(opcode, 19, 16);
11307
11308      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11309      imm32 = Bits32(opcode, 7, 0) << 2;
11310      regs = Bits32(opcode, 7, 0);
11311
11312      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11313      // UNPREDICTABLE;
11314      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11315        return false;
11316
11317      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11318      if ((regs == 0) || ((d + regs) > 32))
11319        return false;
11320      break;
11321
11322    default:
11323      return false;
11324    }
11325
11326    RegisterInfo base_reg;
11327    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11328
11329    uint32_t Rn = ReadCoreReg(n, &success);
11330    if (!success)
11331      return false;
11332
11333    // address = if add then R[n] else R[n]-imm32;
11334    addr_t address;
11335    if (add)
11336      address = Rn;
11337    else
11338      address = Rn - imm32;
11339
11340    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11341    EmulateInstruction::Context context;
11342
11343    if (wback) {
11344      uint32_t value;
11345      if (add)
11346        value = Rn + imm32;
11347      else
11348        value = Rn - imm32;
11349
11350      context.type = eContextAdjustBaseRegister;
11351      context.SetImmediateSigned(value - Rn);
11352      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11353                                 value))
11354        return false;
11355    }
11356
11357    const uint32_t addr_byte_size = GetAddressByteSize();
11358    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11359
11360    context.type = eContextRegisterLoad;
11361
11362    // for r = 0 to regs-1
11363    for (uint32_t r = 0; r < regs; ++r) {
11364      if (single_regs) {
11365        // S[d+r] = MemA[address,4]; address = address+4;
11366        context.SetRegisterPlusOffset(base_reg, address - Rn);
11367
11368        uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11369        if (!success)
11370          return false;
11371
11372        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11373                                   start_reg + d + r, data))
11374          return false;
11375
11376        address = address + 4;
11377      } else {
11378        // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
11379        // address+8;
11380        context.SetRegisterPlusOffset(base_reg, address - Rn);
11381        uint32_t word1 =
11382            MemARead(context, address, addr_byte_size, 0, &success);
11383        if (!success)
11384          return false;
11385
11386        context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
11387        uint32_t word2 =
11388            MemARead(context, address + 4, addr_byte_size, 0, &success);
11389        if (!success)
11390          return false;
11391
11392        address = address + 8;
11393        // // Combine the word-aligned words in the correct order for current
11394        // endianness.
11395        // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
11396        uint64_t data;
11397        if (GetByteOrder() == eByteOrderBig) {
11398          data = word1;
11399          data = (data << 32) | word2;
11400        } else {
11401          data = word2;
11402          data = (data << 32) | word1;
11403        }
11404
11405        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
11406                                   start_reg + d + r, data))
11407          return false;
11408      }
11409    }
11410  }
11411  return true;
11412}
11413
11414// A8.6.399 VSTM
11415// Vector Store Multiple stores multiple extension registers to consecutive
11416// memory locations using an address from an
11417// ARM core register.
11418bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
11419                                        const ARMEncoding encoding) {
11420#if 0
11421    if ConditionPassed() then
11422        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11423        address = if add then R[n] else R[n]-imm32;
11424        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11425        for r = 0 to regs-1
11426            if single_regs then
11427                MemA[address,4] = S[d+r]; address = address+4;
11428            else
11429                // Store as two word-aligned words in the correct order for
11430                // current endianness.
11431                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11432                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11433                address = address+8;
11434#endif
11435
11436  bool success = false;
11437
11438  if (ConditionPassed(opcode)) {
11439    bool single_regs;
11440    bool add;
11441    bool wback;
11442    uint32_t d;
11443    uint32_t n;
11444    uint32_t imm32;
11445    uint32_t regs;
11446
11447    switch (encoding) {
11448    case eEncodingT1:
11449    case eEncodingA1:
11450      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11451      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11452      // if P == '1' && W == '0' then SEE VSTR;
11453      // if P == U && W == '1' then UNDEFINED;
11454      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11455        return false;
11456
11457      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11458      // !), 101 (DB with !)
11459      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11460      single_regs = false;
11461      add = BitIsSet(opcode, 23);
11462      wback = BitIsSet(opcode, 21);
11463
11464      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11465      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11466      n = Bits32(opcode, 19, 16);
11467      imm32 = Bits32(opcode, 7, 0) << 2;
11468
11469      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11470      regs = Bits32(opcode, 7, 0) / 2;
11471
11472      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11473      // UNPREDICTABLE;
11474      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11475        return false;
11476
11477      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11478      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11479        return false;
11480
11481      break;
11482
11483    case eEncodingT2:
11484    case eEncodingA2:
11485      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11486      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11487      // if P == '1' && W == '0' then SEE VSTR;
11488      // if P == U && W == '1' then UNDEFINED;
11489      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11490        return false;
11491
11492      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11493      // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
11494      // == '1'); d =
11495      // UInt(Vd:D); n = UInt(Rn);
11496      single_regs = true;
11497      add = BitIsSet(opcode, 23);
11498      wback = BitIsSet(opcode, 21);
11499      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11500      n = Bits32(opcode, 19, 16);
11501
11502      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11503      imm32 = Bits32(opcode, 7, 0) << 2;
11504      regs = Bits32(opcode, 7, 0);
11505
11506      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11507      // UNPREDICTABLE;
11508      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11509        return false;
11510
11511      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11512      if ((regs == 0) || ((d + regs) > 32))
11513        return false;
11514
11515      break;
11516
11517    default:
11518      return false;
11519    }
11520
11521    RegisterInfo base_reg;
11522    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11523
11524    uint32_t Rn = ReadCoreReg(n, &success);
11525    if (!success)
11526      return false;
11527
11528    // address = if add then R[n] else R[n]-imm32;
11529    addr_t address;
11530    if (add)
11531      address = Rn;
11532    else
11533      address = Rn - imm32;
11534
11535    EmulateInstruction::Context context;
11536    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11537    if (wback) {
11538      uint32_t value;
11539      if (add)
11540        value = Rn + imm32;
11541      else
11542        value = Rn - imm32;
11543
11544      context.type = eContextAdjustBaseRegister;
11545      context.SetRegisterPlusOffset(base_reg, value - Rn);
11546
11547      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11548                                 value))
11549        return false;
11550    }
11551
11552    const uint32_t addr_byte_size = GetAddressByteSize();
11553    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11554
11555    context.type = eContextRegisterStore;
11556    // for r = 0 to regs-1
11557    for (uint32_t r = 0; r < regs; ++r) {
11558
11559      if (single_regs) {
11560        // MemA[address,4] = S[d+r]; address = address+4;
11561        uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11562                                             start_reg + d + r, 0, &success);
11563        if (!success)
11564          return false;
11565
11566        RegisterInfo data_reg;
11567        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11568        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11569                                                address - Rn);
11570        if (!MemAWrite(context, address, data, addr_byte_size))
11571          return false;
11572
11573        address = address + 4;
11574      } else {
11575        // // Store as two word-aligned words in the correct order for current
11576        // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11577        // D[d+r]<31:0>;
11578        // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11579        // D[d+r]<63:32>;
11580        uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11581                                             start_reg + d + r, 0, &success);
11582        if (!success)
11583          return false;
11584
11585        RegisterInfo data_reg;
11586        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11587
11588        if (GetByteOrder() == eByteOrderBig) {
11589          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11590                                                  address - Rn);
11591          if (!MemAWrite(context, address, Bits64(data, 63, 32),
11592                         addr_byte_size))
11593            return false;
11594
11595          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11596                                                  (address + 4) - Rn);
11597          if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11598                         addr_byte_size))
11599            return false;
11600        } else {
11601          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11602                                                  address - Rn);
11603          if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11604            return false;
11605
11606          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11607                                                  (address + 4) - Rn);
11608          if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11609                         addr_byte_size))
11610            return false;
11611        }
11612        // address = address+8;
11613        address = address + 8;
11614      }
11615    }
11616  }
11617  return true;
11618}
11619
11620// A8.6.320
11621// This instruction loads a single extension register from memory, using an
11622// address from an ARM core register, with an optional offset.
11623bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11624                                        ARMEncoding encoding) {
11625#if 0
11626    if ConditionPassed() then
11627        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11628        base = if n == 15 then Align(PC,4) else R[n];
11629        address = if add then (base + imm32) else (base - imm32);
11630        if single_reg then
11631            S[d] = MemA[address,4];
11632        else
11633            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11634            // Combine the word-aligned words in the correct order for current
11635            // endianness.
11636            D[d] = if BigEndian() then word1:word2 else word2:word1;
11637#endif
11638
11639  bool success = false;
11640
11641  if (ConditionPassed(opcode)) {
11642    bool single_reg;
11643    bool add;
11644    uint32_t imm32;
11645    uint32_t d;
11646    uint32_t n;
11647
11648    switch (encoding) {
11649    case eEncodingT1:
11650    case eEncodingA1:
11651      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11652      // 32);
11653      single_reg = false;
11654      add = BitIsSet(opcode, 23);
11655      imm32 = Bits32(opcode, 7, 0) << 2;
11656
11657      // d = UInt(D:Vd); n = UInt(Rn);
11658      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11659      n = Bits32(opcode, 19, 16);
11660
11661      break;
11662
11663    case eEncodingT2:
11664    case eEncodingA2:
11665      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11666      single_reg = true;
11667      add = BitIsSet(opcode, 23);
11668      imm32 = Bits32(opcode, 7, 0) << 2;
11669
11670      // d = UInt(Vd:D); n = UInt(Rn);
11671      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11672      n = Bits32(opcode, 19, 16);
11673
11674      break;
11675
11676    default:
11677      return false;
11678    }
11679    RegisterInfo base_reg;
11680    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11681
11682    uint32_t Rn = ReadCoreReg(n, &success);
11683    if (!success)
11684      return false;
11685
11686    // base = if n == 15 then Align(PC,4) else R[n];
11687    uint32_t base;
11688    if (n == 15)
11689      base = AlignPC(Rn);
11690    else
11691      base = Rn;
11692
11693    // address = if add then (base + imm32) else (base - imm32);
11694    addr_t address;
11695    if (add)
11696      address = base + imm32;
11697    else
11698      address = base - imm32;
11699
11700    const uint32_t addr_byte_size = GetAddressByteSize();
11701    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11702
11703    EmulateInstruction::Context context;
11704    context.type = eContextRegisterLoad;
11705    context.SetRegisterPlusOffset(base_reg, address - base);
11706
11707    if (single_reg) {
11708      // S[d] = MemA[address,4];
11709      uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11710      if (!success)
11711        return false;
11712
11713      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11714                                 data))
11715        return false;
11716    } else {
11717      // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11718      uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11719      if (!success)
11720        return false;
11721
11722      context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11723      uint32_t word2 =
11724          MemARead(context, address + 4, addr_byte_size, 0, &success);
11725      if (!success)
11726        return false;
11727      // // Combine the word-aligned words in the correct order for current
11728      // endianness.
11729      // D[d] = if BigEndian() then word1:word2 else word2:word1;
11730      uint64_t data64;
11731      if (GetByteOrder() == eByteOrderBig) {
11732        data64 = word1;
11733        data64 = (data64 << 32) | word2;
11734      } else {
11735        data64 = word2;
11736        data64 = (data64 << 32) | word1;
11737      }
11738
11739      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11740                                 data64))
11741        return false;
11742    }
11743  }
11744  return true;
11745}
11746
11747// A8.6.400 VSTR
11748// This instruction stores a signle extension register to memory, using an
11749// address from an ARM core register, with an optional offset.
11750bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11751                                        ARMEncoding encoding) {
11752#if 0
11753    if ConditionPassed() then
11754        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11755        address = if add then (R[n] + imm32) else (R[n] - imm32);
11756        if single_reg then
11757            MemA[address,4] = S[d];
11758        else
11759            // Store as two word-aligned words in the correct order for current
11760            // endianness.
11761            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11762            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11763#endif
11764
11765  bool success = false;
11766
11767  if (ConditionPassed(opcode)) {
11768    bool single_reg;
11769    bool add;
11770    uint32_t imm32;
11771    uint32_t d;
11772    uint32_t n;
11773
11774    switch (encoding) {
11775    case eEncodingT1:
11776    case eEncodingA1:
11777      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11778      // 32);
11779      single_reg = false;
11780      add = BitIsSet(opcode, 23);
11781      imm32 = Bits32(opcode, 7, 0) << 2;
11782
11783      // d = UInt(D:Vd); n = UInt(Rn);
11784      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11785      n = Bits32(opcode, 19, 16);
11786
11787      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11788      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11789        return false;
11790
11791      break;
11792
11793    case eEncodingT2:
11794    case eEncodingA2:
11795      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11796      single_reg = true;
11797      add = BitIsSet(opcode, 23);
11798      imm32 = Bits32(opcode, 7, 0) << 2;
11799
11800      // d = UInt(Vd:D); n = UInt(Rn);
11801      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11802      n = Bits32(opcode, 19, 16);
11803
11804      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11805      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11806        return false;
11807
11808      break;
11809
11810    default:
11811      return false;
11812    }
11813
11814    RegisterInfo base_reg;
11815    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11816
11817    uint32_t Rn = ReadCoreReg(n, &success);
11818    if (!success)
11819      return false;
11820
11821    // address = if add then (R[n] + imm32) else (R[n] - imm32);
11822    addr_t address;
11823    if (add)
11824      address = Rn + imm32;
11825    else
11826      address = Rn - imm32;
11827
11828    const uint32_t addr_byte_size = GetAddressByteSize();
11829    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11830
11831    RegisterInfo data_reg;
11832    GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11833    EmulateInstruction::Context context;
11834    context.type = eContextRegisterStore;
11835    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11836
11837    if (single_reg) {
11838      // MemA[address,4] = S[d];
11839      uint32_t data =
11840          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11841      if (!success)
11842        return false;
11843
11844      if (!MemAWrite(context, address, data, addr_byte_size))
11845        return false;
11846    } else {
11847      // // Store as two word-aligned words in the correct order for current
11848      // endianness.
11849      // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11850      // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11851      uint64_t data =
11852          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11853      if (!success)
11854        return false;
11855
11856      if (GetByteOrder() == eByteOrderBig) {
11857        if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11858          return false;
11859
11860        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11861                                                (address + 4) - Rn);
11862        if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11863                       addr_byte_size))
11864          return false;
11865      } else {
11866        if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11867          return false;
11868
11869        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11870                                                (address + 4) - Rn);
11871        if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11872                       addr_byte_size))
11873          return false;
11874      }
11875    }
11876  }
11877  return true;
11878}
11879
11880// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
11881// from memory into one, two, three or four registers, without de-interleaving.
11882// Every element of each register is loaded.
11883bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11884                                                ARMEncoding encoding) {
11885#if 0
11886    if ConditionPassed() then
11887        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11888        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11889        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11890        for r = 0 to regs-1
11891            for e = 0 to elements-1
11892                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11893                address = address + ebytes;
11894#endif
11895
11896  bool success = false;
11897
11898  if (ConditionPassed(opcode)) {
11899    uint32_t regs;
11900    uint32_t alignment;
11901    uint32_t ebytes;
11902    uint32_t esize;
11903    uint32_t elements;
11904    uint32_t d;
11905    uint32_t n;
11906    uint32_t m;
11907    bool wback;
11908    bool register_index;
11909
11910    switch (encoding) {
11911    case eEncodingT1:
11912    case eEncodingA1: {
11913      // case type of
11914      // when '0111'
11915      // regs = 1; if align<1> == '1' then UNDEFINED;
11916      // when '1010'
11917      // regs = 2; if align == '11' then UNDEFINED;
11918      // when '0110'
11919      // regs = 3; if align<1> == '1' then UNDEFINED;
11920      // when '0010'
11921      // regs = 4;
11922      // otherwise
11923      // SEE 'Related encodings';
11924      uint32_t type = Bits32(opcode, 11, 8);
11925      uint32_t align = Bits32(opcode, 5, 4);
11926      if (type == 7) // '0111'
11927      {
11928        regs = 1;
11929        if (BitIsSet(align, 1))
11930          return false;
11931      } else if (type == 10) // '1010'
11932      {
11933        regs = 2;
11934        if (align == 3)
11935          return false;
11936
11937      } else if (type == 6) // '0110'
11938      {
11939        regs = 3;
11940        if (BitIsSet(align, 1))
11941          return false;
11942      } else if (type == 2) // '0010'
11943      {
11944        regs = 4;
11945      } else
11946        return false;
11947
11948      // alignment = if align == '00' then 1 else 4 << UInt(align);
11949      if (align == 0)
11950        alignment = 1;
11951      else
11952        alignment = 4 << align;
11953
11954      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11955      ebytes = 1 << Bits32(opcode, 7, 6);
11956      esize = 8 * ebytes;
11957      elements = 8 / ebytes;
11958
11959      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11960      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11961      n = Bits32(opcode, 19, 15);
11962      m = Bits32(opcode, 3, 0);
11963
11964      // wback = (m != 15); register_index = (m != 15 && m != 13);
11965      wback = (m != 15);
11966      register_index = ((m != 15) && (m != 13));
11967
11968      // if d+regs > 32 then UNPREDICTABLE;
11969      if ((d + regs) > 32)
11970        return false;
11971    } break;
11972
11973    default:
11974      return false;
11975    }
11976
11977    RegisterInfo base_reg;
11978    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11979
11980    uint32_t Rn = ReadCoreReg(n, &success);
11981    if (!success)
11982      return false;
11983
11984    // address = R[n]; if (address MOD alignment) != 0 then
11985    // GenerateAlignmentException();
11986    addr_t address = Rn;
11987    if ((address % alignment) != 0)
11988      return false;
11989
11990    EmulateInstruction::Context context;
11991    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11992    if (wback) {
11993      uint32_t Rm = ReadCoreReg(m, &success);
11994      if (!success)
11995        return false;
11996
11997      uint32_t offset;
11998      if (register_index)
11999        offset = Rm;
12000      else
12001        offset = 8 * regs;
12002
12003      uint32_t value = Rn + offset;
12004      context.type = eContextAdjustBaseRegister;
12005      context.SetRegisterPlusOffset(base_reg, offset);
12006
12007      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12008                                 value))
12009        return false;
12010    }
12011
12012    // for r = 0 to regs-1
12013    for (uint32_t r = 0; r < regs; ++r) {
12014      // for e = 0 to elements-1
12015      uint64_t assembled_data = 0;
12016      for (uint32_t e = 0; e < elements; ++e) {
12017        // Elem[D[d+r],e,esize] = MemU[address,ebytes];
12018        context.type = eContextRegisterLoad;
12019        context.SetRegisterPlusOffset(base_reg, address - Rn);
12020        uint64_t data = MemURead(context, address, ebytes, 0, &success);
12021        if (!success)
12022          return false;
12023
12024        assembled_data =
12025            (data << (e * esize)) |
12026            assembled_data; // New data goes to the left of existing data
12027
12028        // address = address + ebytes;
12029        address = address + ebytes;
12030      }
12031      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12032                                 assembled_data))
12033        return false;
12034    }
12035  }
12036  return true;
12037}
12038
12039// A8.6.308 VLD1 (single element to one lane)
12040//
12041bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
12042                                              const ARMEncoding encoding) {
12043#if 0
12044    if ConditionPassed() then
12045        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12046        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12047        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12048        Elem[D[d],index,esize] = MemU[address,ebytes];
12049#endif
12050
12051  bool success = false;
12052
12053  if (ConditionPassed(opcode)) {
12054    uint32_t ebytes;
12055    uint32_t esize;
12056    uint32_t index;
12057    uint32_t alignment;
12058    uint32_t d;
12059    uint32_t n;
12060    uint32_t m;
12061    bool wback;
12062    bool register_index;
12063
12064    switch (encoding) {
12065    case eEncodingT1:
12066    case eEncodingA1: {
12067      uint32_t size = Bits32(opcode, 11, 10);
12068      uint32_t index_align = Bits32(opcode, 7, 4);
12069      // if size == '11' then SEE VLD1 (single element to all lanes);
12070      if (size == 3)
12071        return EmulateVLD1SingleAll(opcode, encoding);
12072      // case size of
12073      if (size == 0) // when '00'
12074      {
12075        // if index_align<0> != '0' then UNDEFINED;
12076        if (BitIsClear(index_align, 0))
12077          return false;
12078
12079        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12080        ebytes = 1;
12081        esize = 8;
12082        index = Bits32(index_align, 3, 1);
12083        alignment = 1;
12084      } else if (size == 1) // when '01'
12085      {
12086        // if index_align<1> != '0' then UNDEFINED;
12087        if (BitIsClear(index_align, 1))
12088          return false;
12089
12090        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12091        ebytes = 2;
12092        esize = 16;
12093        index = Bits32(index_align, 3, 2);
12094
12095        // alignment = if index_align<0> == '0' then 1 else 2;
12096        if (BitIsClear(index_align, 0))
12097          alignment = 1;
12098        else
12099          alignment = 2;
12100      } else if (size == 2) // when '10'
12101      {
12102        // if index_align<2> != '0' then UNDEFINED;
12103        if (BitIsClear(index_align, 2))
12104          return false;
12105
12106        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12107        // UNDEFINED;
12108        if ((Bits32(index_align, 1, 0) != 0) &&
12109            (Bits32(index_align, 1, 0) != 3))
12110          return false;
12111
12112        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12113        ebytes = 4;
12114        esize = 32;
12115        index = Bit32(index_align, 3);
12116
12117        // alignment = if index_align<1:0> == '00' then 1 else 4;
12118        if (Bits32(index_align, 1, 0) == 0)
12119          alignment = 1;
12120        else
12121          alignment = 4;
12122      } else {
12123        return false;
12124      }
12125      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12126      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12127      n = Bits32(opcode, 19, 16);
12128      m = Bits32(opcode, 3, 0);
12129
12130      // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
12131      // then UNPREDICTABLE;
12132      wback = (m != 15);
12133      register_index = ((m != 15) && (m != 13));
12134
12135      if (n == 15)
12136        return false;
12137
12138    } break;
12139
12140    default:
12141      return false;
12142    }
12143
12144    RegisterInfo base_reg;
12145    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12146
12147    uint32_t Rn = ReadCoreReg(n, &success);
12148    if (!success)
12149      return false;
12150
12151    // address = R[n]; if (address MOD alignment) != 0 then
12152    // GenerateAlignmentException();
12153    addr_t address = Rn;
12154    if ((address % alignment) != 0)
12155      return false;
12156
12157    EmulateInstruction::Context context;
12158    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12159    if (wback) {
12160      uint32_t Rm = ReadCoreReg(m, &success);
12161      if (!success)
12162        return false;
12163
12164      uint32_t offset;
12165      if (register_index)
12166        offset = Rm;
12167      else
12168        offset = ebytes;
12169
12170      uint32_t value = Rn + offset;
12171
12172      context.type = eContextAdjustBaseRegister;
12173      context.SetRegisterPlusOffset(base_reg, offset);
12174
12175      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12176                                 value))
12177        return false;
12178    }
12179
12180    // Elem[D[d],index,esize] = MemU[address,ebytes];
12181    uint32_t element = MemURead(context, address, esize, 0, &success);
12182    if (!success)
12183      return false;
12184
12185    element = element << (index * esize);
12186
12187    uint64_t reg_data =
12188        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12189    if (!success)
12190      return false;
12191
12192    uint64_t all_ones = -1;
12193    uint64_t mask = all_ones
12194                    << ((index + 1) * esize); // mask is all 1's to left of
12195                                              // where 'element' goes, & all 0's
12196    // at element & to the right of element.
12197    if (index > 0)
12198      mask = mask | Bits64(all_ones, (index * esize) - 1,
12199                           0); // add 1's to the right of where 'element' goes.
12200    // now mask should be 0's where element goes & 1's everywhere else.
12201
12202    uint64_t masked_reg =
12203        reg_data & mask; // Take original reg value & zero out 'element' bits
12204    reg_data =
12205        masked_reg & element; // Put 'element' into those bits in reg_data.
12206
12207    context.type = eContextRegisterLoad;
12208    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
12209                               reg_data))
12210      return false;
12211  }
12212  return true;
12213}
12214
12215// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
12216// elements) stores elements to memory from one, two, three, or four registers,
12217// without interleaving.  Every element of each register is stored.
12218bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
12219                                                ARMEncoding encoding) {
12220#if 0
12221    if ConditionPassed() then
12222        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12223        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12224        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12225        for r = 0 to regs-1
12226            for e = 0 to elements-1
12227                MemU[address,ebytes] = Elem[D[d+r],e,esize];
12228                address = address + ebytes;
12229#endif
12230
12231  bool success = false;
12232
12233  if (ConditionPassed(opcode)) {
12234    uint32_t regs;
12235    uint32_t alignment;
12236    uint32_t ebytes;
12237    uint32_t esize;
12238    uint32_t elements;
12239    uint32_t d;
12240    uint32_t n;
12241    uint32_t m;
12242    bool wback;
12243    bool register_index;
12244
12245    switch (encoding) {
12246    case eEncodingT1:
12247    case eEncodingA1: {
12248      uint32_t type = Bits32(opcode, 11, 8);
12249      uint32_t align = Bits32(opcode, 5, 4);
12250
12251      // case type of
12252      if (type == 7) // when '0111'
12253      {
12254        // regs = 1; if align<1> == '1' then UNDEFINED;
12255        regs = 1;
12256        if (BitIsSet(align, 1))
12257          return false;
12258      } else if (type == 10) // when '1010'
12259      {
12260        // regs = 2; if align == '11' then UNDEFINED;
12261        regs = 2;
12262        if (align == 3)
12263          return false;
12264      } else if (type == 6) // when '0110'
12265      {
12266        // regs = 3; if align<1> == '1' then UNDEFINED;
12267        regs = 3;
12268        if (BitIsSet(align, 1))
12269          return false;
12270      } else if (type == 2) // when '0010'
12271        // regs = 4;
12272        regs = 4;
12273      else // otherwise
12274        // SEE 'Related encodings';
12275        return false;
12276
12277      // alignment = if align == '00' then 1 else 4 << UInt(align);
12278      if (align == 0)
12279        alignment = 1;
12280      else
12281        alignment = 4 << align;
12282
12283      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
12284      ebytes = 1 << Bits32(opcode, 7, 6);
12285      esize = 8 * ebytes;
12286      elements = 8 / ebytes;
12287
12288      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12289      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12290      n = Bits32(opcode, 19, 16);
12291      m = Bits32(opcode, 3, 0);
12292
12293      // wback = (m != 15); register_index = (m != 15 && m != 13);
12294      wback = (m != 15);
12295      register_index = ((m != 15) && (m != 13));
12296
12297      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12298      if ((d + regs) > 32)
12299        return false;
12300
12301      if (n == 15)
12302        return false;
12303
12304    } break;
12305
12306    default:
12307      return false;
12308    }
12309
12310    RegisterInfo base_reg;
12311    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12312
12313    uint32_t Rn = ReadCoreReg(n, &success);
12314    if (!success)
12315      return false;
12316
12317    // address = R[n]; if (address MOD alignment) != 0 then
12318    // GenerateAlignmentException();
12319    addr_t address = Rn;
12320    if ((address % alignment) != 0)
12321      return false;
12322
12323    EmulateInstruction::Context context;
12324    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
12325    if (wback) {
12326      uint32_t Rm = ReadCoreReg(m, &success);
12327      if (!success)
12328        return false;
12329
12330      uint32_t offset;
12331      if (register_index)
12332        offset = Rm;
12333      else
12334        offset = 8 * regs;
12335
12336      context.type = eContextAdjustBaseRegister;
12337      context.SetRegisterPlusOffset(base_reg, offset);
12338
12339      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12340                                 Rn + offset))
12341        return false;
12342    }
12343
12344    RegisterInfo data_reg;
12345    context.type = eContextRegisterStore;
12346    // for r = 0 to regs-1
12347    for (uint32_t r = 0; r < regs; ++r) {
12348      GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
12349      uint64_t register_data = ReadRegisterUnsigned(
12350          eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
12351      if (!success)
12352        return false;
12353
12354      // for e = 0 to elements-1
12355      for (uint32_t e = 0; e < elements; ++e) {
12356        // MemU[address,ebytes] = Elem[D[d+r],e,esize];
12357        uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
12358
12359        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
12360                                                address - Rn);
12361        if (!MemUWrite(context, address, word, ebytes))
12362          return false;
12363
12364        // address = address + ebytes;
12365        address = address + ebytes;
12366      }
12367    }
12368  }
12369  return true;
12370}
12371
12372// A8.6.392 VST1 (single element from one lane) This instruction stores one
12373// element to memory from one element of a register.
12374bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
12375                                              ARMEncoding encoding) {
12376#if 0
12377    if ConditionPassed() then
12378        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12379        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12380        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12381        MemU[address,ebytes] = Elem[D[d],index,esize];
12382#endif
12383
12384  bool success = false;
12385
12386  if (ConditionPassed(opcode)) {
12387    uint32_t ebytes;
12388    uint32_t esize;
12389    uint32_t index;
12390    uint32_t alignment;
12391    uint32_t d;
12392    uint32_t n;
12393    uint32_t m;
12394    bool wback;
12395    bool register_index;
12396
12397    switch (encoding) {
12398    case eEncodingT1:
12399    case eEncodingA1: {
12400      uint32_t size = Bits32(opcode, 11, 10);
12401      uint32_t index_align = Bits32(opcode, 7, 4);
12402
12403      // if size == '11' then UNDEFINED;
12404      if (size == 3)
12405        return false;
12406
12407      // case size of
12408      if (size == 0) // when '00'
12409      {
12410        // if index_align<0> != '0' then UNDEFINED;
12411        if (BitIsClear(index_align, 0))
12412          return false;
12413        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
12414        ebytes = 1;
12415        esize = 8;
12416        index = Bits32(index_align, 3, 1);
12417        alignment = 1;
12418      } else if (size == 1) // when '01'
12419      {
12420        // if index_align<1> != '0' then UNDEFINED;
12421        if (BitIsClear(index_align, 1))
12422          return false;
12423
12424        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
12425        ebytes = 2;
12426        esize = 16;
12427        index = Bits32(index_align, 3, 2);
12428
12429        // alignment = if index_align<0> == '0' then 1 else 2;
12430        if (BitIsClear(index_align, 0))
12431          alignment = 1;
12432        else
12433          alignment = 2;
12434      } else if (size == 2) // when '10'
12435      {
12436        // if index_align<2> != '0' then UNDEFINED;
12437        if (BitIsClear(index_align, 2))
12438          return false;
12439
12440        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
12441        // UNDEFINED;
12442        if ((Bits32(index_align, 1, 0) != 0) &&
12443            (Bits32(index_align, 1, 0) != 3))
12444          return false;
12445
12446        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12447        ebytes = 4;
12448        esize = 32;
12449        index = Bit32(index_align, 3);
12450
12451        // alignment = if index_align<1:0> == '00' then 1 else 4;
12452        if (Bits32(index_align, 1, 0) == 0)
12453          alignment = 1;
12454        else
12455          alignment = 4;
12456      } else {
12457        return false;
12458      }
12459      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12460      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12461      n = Bits32(opcode, 19, 16);
12462      m = Bits32(opcode, 3, 0);
12463
12464      // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12465      // then UNPREDICTABLE;
12466      wback = (m != 15);
12467      register_index = ((m != 15) && (m != 13));
12468
12469      if (n == 15)
12470        return false;
12471    } break;
12472
12473    default:
12474      return false;
12475    }
12476
12477    RegisterInfo base_reg;
12478    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12479
12480    uint32_t Rn = ReadCoreReg(n, &success);
12481    if (!success)
12482      return false;
12483
12484    // address = R[n]; if (address MOD alignment) != 0 then
12485    // GenerateAlignmentException();
12486    addr_t address = Rn;
12487    if ((address % alignment) != 0)
12488      return false;
12489
12490    EmulateInstruction::Context context;
12491    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12492    if (wback) {
12493      uint32_t Rm = ReadCoreReg(m, &success);
12494      if (!success)
12495        return false;
12496
12497      uint32_t offset;
12498      if (register_index)
12499        offset = Rm;
12500      else
12501        offset = ebytes;
12502
12503      context.type = eContextAdjustBaseRegister;
12504      context.SetRegisterPlusOffset(base_reg, offset);
12505
12506      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12507                                 Rn + offset))
12508        return false;
12509    }
12510
12511    // MemU[address,ebytes] = Elem[D[d],index,esize];
12512    uint64_t register_data =
12513        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12514    if (!success)
12515      return false;
12516
12517    uint64_t word =
12518        Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12519
12520    RegisterInfo data_reg;
12521    GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12522    context.type = eContextRegisterStore;
12523    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12524
12525    if (!MemUWrite(context, address, word, ebytes))
12526      return false;
12527  }
12528  return true;
12529}
12530
12531// A8.6.309 VLD1 (single element to all lanes) This instruction loads one
12532// element from memory into every element of one or two vectors.
12533bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12534                                                 const ARMEncoding encoding) {
12535#if 0
12536    if ConditionPassed() then
12537        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12538        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12539        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12540        replicated_element = Replicate(MemU[address,ebytes], elements);
12541        for r = 0 to regs-1
12542            D[d+r] = replicated_element;
12543#endif
12544
12545  bool success = false;
12546
12547  if (ConditionPassed(opcode)) {
12548    uint32_t ebytes;
12549    uint32_t elements;
12550    uint32_t regs;
12551    uint32_t alignment;
12552    uint32_t d;
12553    uint32_t n;
12554    uint32_t m;
12555    bool wback;
12556    bool register_index;
12557
12558    switch (encoding) {
12559    case eEncodingT1:
12560    case eEncodingA1: {
12561      // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12562      uint32_t size = Bits32(opcode, 7, 6);
12563      if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12564        return false;
12565
12566      // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12567      // then 1 else 2;
12568      ebytes = 1 << size;
12569      elements = 8 / ebytes;
12570      if (BitIsClear(opcode, 5))
12571        regs = 1;
12572      else
12573        regs = 2;
12574
12575      // alignment = if a == '0' then 1 else ebytes;
12576      if (BitIsClear(opcode, 4))
12577        alignment = 1;
12578      else
12579        alignment = ebytes;
12580
12581      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12582      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12583      n = Bits32(opcode, 19, 16);
12584      m = Bits32(opcode, 3, 0);
12585
12586      // wback = (m != 15); register_index = (m != 15 && m != 13);
12587      wback = (m != 15);
12588      register_index = ((m != 15) && (m != 13));
12589
12590      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12591      if ((d + regs) > 32)
12592        return false;
12593
12594      if (n == 15)
12595        return false;
12596    } break;
12597
12598    default:
12599      return false;
12600    }
12601
12602    RegisterInfo base_reg;
12603    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12604
12605    uint32_t Rn = ReadCoreReg(n, &success);
12606    if (!success)
12607      return false;
12608
12609    // address = R[n]; if (address MOD alignment) != 0 then
12610    // GenerateAlignmentException();
12611    addr_t address = Rn;
12612    if ((address % alignment) != 0)
12613      return false;
12614
12615    EmulateInstruction::Context context;
12616    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12617    if (wback) {
12618      uint32_t Rm = ReadCoreReg(m, &success);
12619      if (!success)
12620        return false;
12621
12622      uint32_t offset;
12623      if (register_index)
12624        offset = Rm;
12625      else
12626        offset = ebytes;
12627
12628      context.type = eContextAdjustBaseRegister;
12629      context.SetRegisterPlusOffset(base_reg, offset);
12630
12631      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12632                                 Rn + offset))
12633        return false;
12634    }
12635
12636    // replicated_element = Replicate(MemU[address,ebytes], elements);
12637
12638    context.type = eContextRegisterLoad;
12639    uint64_t word = MemURead(context, address, ebytes, 0, &success);
12640    if (!success)
12641      return false;
12642
12643    uint64_t replicated_element = 0;
12644    uint32_t esize = ebytes * 8;
12645    for (uint32_t e = 0; e < elements; ++e)
12646      replicated_element =
12647          (replicated_element << esize) | Bits64(word, esize - 1, 0);
12648
12649    // for r = 0 to regs-1
12650    for (uint32_t r = 0; r < regs; ++r) {
12651      // D[d+r] = replicated_element;
12652      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12653                                 replicated_element))
12654        return false;
12655    }
12656  }
12657  return true;
12658}
12659
12660// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
12661// instruction provides an exception return without the use of the stack.  It
12662// subtracts the immediate constant from the LR, branches to the resulting
12663// address, and also copies the SPSR to the CPSR.
12664bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12665                                               const ARMEncoding encoding) {
12666#if 0
12667    if ConditionPassed() then
12668        EncodingSpecificOperations();
12669        if CurrentInstrSet() == InstrSet_ThumbEE then
12670            UNPREDICTABLE;
12671        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12672        case opcode of
12673            when '0000' result = R[n] AND operand2; // AND
12674            when '0001' result = R[n] EOR operand2; // EOR
12675            when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12676            when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12677            when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12678            when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12679            when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12680            when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12681            when '1100' result = R[n] OR operand2; // ORR
12682            when '1101' result = operand2; // MOV
12683            when '1110' result = R[n] AND NOT(operand2); // BIC
12684            when '1111' result = NOT(operand2); // MVN
12685        CPSRWriteByInstr(SPSR[], '1111', TRUE);
12686        BranchWritePC(result);
12687#endif
12688
12689  bool success = false;
12690
12691  if (ConditionPassed(opcode)) {
12692    uint32_t n;
12693    uint32_t m;
12694    uint32_t imm32;
12695    bool register_form;
12696    ARM_ShifterType shift_t;
12697    uint32_t shift_n;
12698    uint32_t code;
12699
12700    switch (encoding) {
12701    case eEncodingT1:
12702      // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
12703      // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
12704      // // = SUB
12705      n = 14;
12706      imm32 = Bits32(opcode, 7, 0);
12707      register_form = false;
12708      code = 2;
12709
12710      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12711      if (InITBlock() && !LastInITBlock())
12712        return false;
12713
12714      break;
12715
12716    case eEncodingA1:
12717      // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12718      n = Bits32(opcode, 19, 16);
12719      imm32 = ARMExpandImm(opcode);
12720      register_form = false;
12721      code = Bits32(opcode, 24, 21);
12722
12723      break;
12724
12725    case eEncodingA2:
12726      // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12727      n = Bits32(opcode, 19, 16);
12728      m = Bits32(opcode, 3, 0);
12729      register_form = true;
12730
12731      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12732      shift_n = DecodeImmShiftARM(opcode, shift_t);
12733
12734      break;
12735
12736    default:
12737      return false;
12738    }
12739
12740    // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12741    // else imm32;
12742    uint32_t operand2;
12743    if (register_form) {
12744      uint32_t Rm = ReadCoreReg(m, &success);
12745      if (!success)
12746        return false;
12747
12748      operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12749      if (!success)
12750        return false;
12751    } else {
12752      operand2 = imm32;
12753    }
12754
12755    uint32_t Rn = ReadCoreReg(n, &success);
12756    if (!success)
12757      return false;
12758
12759    AddWithCarryResult result;
12760
12761    // case opcode of
12762    switch (code) {
12763    case 0: // when '0000'
12764      // result = R[n] AND operand2; // AND
12765      result.result = Rn & operand2;
12766      break;
12767
12768    case 1: // when '0001'
12769      // result = R[n] EOR operand2; // EOR
12770      result.result = Rn ^ operand2;
12771      break;
12772
12773    case 2: // when '0010'
12774      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12775      result = AddWithCarry(Rn, ~(operand2), 1);
12776      break;
12777
12778    case 3: // when '0011'
12779      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12780      result = AddWithCarry(~(Rn), operand2, 1);
12781      break;
12782
12783    case 4: // when '0100'
12784      // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12785      result = AddWithCarry(Rn, operand2, 0);
12786      break;
12787
12788    case 5: // when '0101'
12789      // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12790      result = AddWithCarry(Rn, operand2, APSR_C);
12791      break;
12792
12793    case 6: // when '0110'
12794      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12795      result = AddWithCarry(Rn, ~(operand2), APSR_C);
12796      break;
12797
12798    case 7: // when '0111'
12799      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12800      result = AddWithCarry(~(Rn), operand2, APSR_C);
12801      break;
12802
12803    case 10: // when '1100'
12804      // result = R[n] OR operand2; // ORR
12805      result.result = Rn | operand2;
12806      break;
12807
12808    case 11: // when '1101'
12809      // result = operand2; // MOV
12810      result.result = operand2;
12811      break;
12812
12813    case 12: // when '1110'
12814      // result = R[n] AND NOT(operand2); // BIC
12815      result.result = Rn & ~(operand2);
12816      break;
12817
12818    case 15: // when '1111'
12819      // result = NOT(operand2); // MVN
12820      result.result = ~(operand2);
12821      break;
12822
12823    default:
12824      return false;
12825    }
12826    // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12827
12828    // For now, in emulation mode, we don't have access to the SPSR, so we will
12829    // use the CPSR instead, and hope for the best.
12830    uint32_t spsr =
12831        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12832    if (!success)
12833      return false;
12834
12835    CPSRWriteByInstr(spsr, 15, true);
12836
12837    // BranchWritePC(result);
12838    EmulateInstruction::Context context;
12839    context.type = eContextAdjustPC;
12840    context.SetImmediate(result.result);
12841
12842    BranchWritePC(context, result.result);
12843  }
12844  return true;
12845}
12846
12847EmulateInstructionARM::ARMOpcode *
12848EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12849                                                  uint32_t arm_isa) {
12850  static ARMOpcode g_arm_opcodes[] = {
12851      // Prologue instructions
12852
12853      // push register(s)
12854      {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12855       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12856      {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12857       &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12858
12859      // set r7 to point to a stack offset
12860      {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12861       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12862      {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12863       &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12864      // copy the stack pointer to ip
12865      {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12866       &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12867      {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12868       &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12869      {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12870       &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12871
12872      // adjust the stack pointer
12873      {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12874       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12875      {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12876       &EmulateInstructionARM::EmulateSUBSPReg,
12877       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12878
12879      // push one register
12880      // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12881      {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12882       &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12883
12884      // vector push consecutive extension register(s)
12885      {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12886       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12887      {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12888       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12889
12890      // Epilogue instructions
12891
12892      {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12893       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12894      {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12895       &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12896      {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12897       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12898      {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12899       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12900
12901      // Supervisor Call (previously Software Interrupt)
12902      {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12903       &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12904
12905      // Branch instructions
12906      // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12907      // "bl <label>".
12908      {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12909       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12910      {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12911       &EmulateInstructionARM::EmulateB, "b #imm24"},
12912      {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12913       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12914      {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12915       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12916      // for example, "bx lr"
12917      {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12918       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12919      // bxj
12920      {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12921       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12922
12923      // Data-processing instructions
12924      // adc (immediate)
12925      {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12926       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12927      // adc (register)
12928      {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12929       &EmulateInstructionARM::EmulateADCReg,
12930       "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12931      // add (immediate)
12932      {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12933       &EmulateInstructionARM::EmulateADDImmARM,
12934       "add{s}<c> <Rd>, <Rn>, #const"},
12935      // add (register)
12936      {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12937       &EmulateInstructionARM::EmulateADDReg,
12938       "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12939      // add (register-shifted register)
12940      {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12941       &EmulateInstructionARM::EmulateADDRegShift,
12942       "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12943      // adr
12944      {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12945       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12946      {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12947       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12948      // and (immediate)
12949      {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12950       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12951      // and (register)
12952      {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12953       &EmulateInstructionARM::EmulateANDReg,
12954       "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12955      // bic (immediate)
12956      {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12957       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12958      // bic (register)
12959      {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12960       &EmulateInstructionARM::EmulateBICReg,
12961       "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12962      // eor (immediate)
12963      {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12964       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12965      // eor (register)
12966      {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12967       &EmulateInstructionARM::EmulateEORReg,
12968       "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12969      // orr (immediate)
12970      {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12971       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12972      // orr (register)
12973      {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12974       &EmulateInstructionARM::EmulateORRReg,
12975       "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12976      // rsb (immediate)
12977      {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12978       &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12979      // rsb (register)
12980      {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12981       &EmulateInstructionARM::EmulateRSBReg,
12982       "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12983      // rsc (immediate)
12984      {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12985       &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12986      // rsc (register)
12987      {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12988       &EmulateInstructionARM::EmulateRSCReg,
12989       "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12990      // sbc (immediate)
12991      {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12992       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12993      // sbc (register)
12994      {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12995       &EmulateInstructionARM::EmulateSBCReg,
12996       "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12997      // sub (immediate, ARM)
12998      {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12999       &EmulateInstructionARM::EmulateSUBImmARM,
13000       "sub{s}<c> <Rd>, <Rn>, #<const>"},
13001      // sub (sp minus immediate)
13002      {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13003       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
13004      // sub (register)
13005      {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13006       &EmulateInstructionARM::EmulateSUBReg,
13007       "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
13008      // teq (immediate)
13009      {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13010       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
13011      // teq (register)
13012      {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13013       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13014      // tst (immediate)
13015      {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13016       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
13017      // tst (register)
13018      {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13019       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
13020
13021      // mov (immediate)
13022      {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13023       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
13024      {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
13025       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
13026      // mov (register)
13027      {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13028       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
13029      // mvn (immediate)
13030      {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13031       &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
13032      // mvn (register)
13033      {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13034       &EmulateInstructionARM::EmulateMVNReg,
13035       "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
13036      // cmn (immediate)
13037      {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13038       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13039      // cmn (register)
13040      {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13041       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13042      // cmp (immediate)
13043      {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13044       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
13045      // cmp (register)
13046      {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13047       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
13048      // asr (immediate)
13049      {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
13050       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
13051      // asr (register)
13052      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13053       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
13054      // lsl (immediate)
13055      {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13056       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
13057      // lsl (register)
13058      {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
13059       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
13060      // lsr (immediate)
13061      {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
13062       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
13063      // lsr (register)
13064      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
13065       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
13066      // rrx is a special case encoding of ror (immediate)
13067      {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13068       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
13069      // ror (immediate)
13070      {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
13071       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
13072      // ror (register)
13073      {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
13074       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
13075      // mul
13076      {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
13077       &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
13078
13079      // subs pc, lr and related instructions
13080      {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13081       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13082       "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
13083      {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
13084       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
13085       "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
13086
13087      // Load instructions
13088      {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13089       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13090      {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13091       &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
13092      {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13093       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13094      {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13095       &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
13096      {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13097       &EmulateInstructionARM::EmulateLDRImmediateARM,
13098       "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
13099      {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13100       &EmulateInstructionARM::EmulateLDRRegister,
13101       "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
13102      {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13103       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
13104      {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13105       &EmulateInstructionARM::EmulateLDRBRegister,
13106       "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
13107      {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13108       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13109      {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13110       &EmulateInstructionARM::EmulateLDRHRegister,
13111       "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13112      {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13113       &EmulateInstructionARM::EmulateLDRSBImmediate,
13114       "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
13115      {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13116       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
13117      {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13118       &EmulateInstructionARM::EmulateLDRSBRegister,
13119       "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13120      {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13121       &EmulateInstructionARM::EmulateLDRSHImmediate,
13122       "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
13123      {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13124       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13125      {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13126       &EmulateInstructionARM::EmulateLDRSHRegister,
13127       "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
13128      {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13129       &EmulateInstructionARM::EmulateLDRDImmediate,
13130       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
13131      {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13132       &EmulateInstructionARM::EmulateLDRDRegister,
13133       "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13134      {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13135       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13136      {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13137       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13138      {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13139       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13140      {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13141       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13142      {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13143       &EmulateInstructionARM::EmulateVLD1Multiple,
13144       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13145      {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13146       &EmulateInstructionARM::EmulateVLD1Single,
13147       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13148      {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13149       &EmulateInstructionARM::EmulateVLD1SingleAll,
13150       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13151
13152      // Store instructions
13153      {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13154       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13155      {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13156       &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
13157      {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13158       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13159      {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13160       &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
13161      {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13162       &EmulateInstructionARM::EmulateSTRRegister,
13163       "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
13164      {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
13165       &EmulateInstructionARM::EmulateSTRHRegister,
13166       "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
13167      {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13168       &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
13169      {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13170       &EmulateInstructionARM::EmulateSTRBImmARM,
13171       "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13172      {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
13173       &EmulateInstructionARM::EmulateSTRImmARM,
13174       "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
13175      {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13176       &EmulateInstructionARM::EmulateSTRDImm,
13177       "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
13178      {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
13179       &EmulateInstructionARM::EmulateSTRDReg,
13180       "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
13181      {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13182       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13183      {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13184       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
13185      {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
13186       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
13187      {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
13188       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
13189      {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13190       &EmulateInstructionARM::EmulateVST1Multiple,
13191       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13192      {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
13193       &EmulateInstructionARM::EmulateVST1Single,
13194       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13195
13196      // Other instructions
13197      {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13198       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
13199      {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13200       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
13201      {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13202       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
13203      {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13204       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
13205      {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
13206       &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
13207
13208  };
13209  static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
13210
13211  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
13212    if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
13213        (g_arm_opcodes[i].variants & arm_isa) != 0)
13214      return &g_arm_opcodes[i];
13215  }
13216  return nullptr;
13217}
13218
13219EmulateInstructionARM::ARMOpcode *
13220EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
13221                                                    uint32_t arm_isa) {
13222
13223  static ARMOpcode g_thumb_opcodes[] = {
13224      // Prologue instructions
13225
13226      // push register(s)
13227      {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
13228       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
13229      {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13230       &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
13231      {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13232       &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
13233
13234      // set r7 to point to a stack offset
13235      {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13236       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
13237      // copy the stack pointer to r7
13238      {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
13239       &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
13240      // move from high register to low register (comes after "mov r7, sp" to
13241      // resolve ambiguity)
13242      {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
13243       &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
13244
13245      // PC-relative load into register (see also EmulateADDSPRm)
13246      {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13247       &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
13248
13249      // adjust the stack pointer
13250      {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
13251       &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
13252      {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13253       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
13254      {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13255       &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
13256      {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13257       &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
13258      {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13259       &EmulateInstructionARM::EmulateSUBSPReg,
13260       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
13261
13262      // vector push consecutive extension register(s)
13263      {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13264       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
13265      {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13266       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
13267
13268      // Epilogue instructions
13269
13270      {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13271       &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
13272      {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13273       &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
13274      {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13275       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
13276      {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13277       &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
13278      {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13279       &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
13280      {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13281       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
13282      {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13283       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
13284
13285      // Supervisor Call (previously Software Interrupt)
13286      {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13287       &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
13288
13289      // If Then makes up to four following instructions conditional.
13290      // The next 5 opcode _must_ come before the if then instruction
13291      {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13292       &EmulateInstructionARM::EmulateNop, "nop"},
13293      {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13294       &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
13295      {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13296       &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
13297      {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13298       &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
13299      {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
13300       &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
13301      {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13302       &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
13303
13304      // Branch instructions
13305      // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
13306      {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13307       &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
13308      {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13309       &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
13310      {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13311       &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
13312      {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13313       &EmulateInstructionARM::EmulateB,
13314       "b<c>.w #imm8 (outside or last in IT)"},
13315      // J1 == J2 == 1
13316      {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
13317       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
13318      // J1 == J2 == 1
13319      {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
13320       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
13321      {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
13322       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
13323      // for example, "bx lr"
13324      {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
13325       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
13326      // bxj
13327      {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
13328       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
13329      // compare and branch
13330      {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13331       &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
13332      // table branch byte
13333      {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13334       &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
13335      // table branch halfword
13336      {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13337       &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
13338
13339      // Data-processing instructions
13340      // adc (immediate)
13341      {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13342       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
13343      // adc (register)
13344      {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
13345       &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
13346      {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13347       &EmulateInstructionARM::EmulateADCReg,
13348       "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13349      // add (register)
13350      {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13351       &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
13352      // Make sure "add sp, <Rm>" comes before this instruction, so there's no
13353      // ambiguity decoding the two.
13354      {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
13355       &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
13356      // adr
13357      {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13358       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13359      {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13360       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
13361      {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13362       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
13363      // and (immediate)
13364      {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13365       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
13366      // and (register)
13367      {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13368       &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
13369      {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13370       &EmulateInstructionARM::EmulateANDReg,
13371       "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13372      // bic (immediate)
13373      {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13374       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
13375      // bic (register)
13376      {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
13377       &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
13378      {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13379       &EmulateInstructionARM::EmulateBICReg,
13380       "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13381      // eor (immediate)
13382      {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13383       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
13384      // eor (register)
13385      {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
13386       &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
13387      {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13388       &EmulateInstructionARM::EmulateEORReg,
13389       "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13390      // orr (immediate)
13391      {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13392       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
13393      // orr (register)
13394      {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
13395       &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
13396      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13397       &EmulateInstructionARM::EmulateORRReg,
13398       "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13399      // rsb (immediate)
13400      {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
13401       &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
13402      {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13403       &EmulateInstructionARM::EmulateRSBImm,
13404       "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
13405      // rsb (register)
13406      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13407       &EmulateInstructionARM::EmulateRSBReg,
13408       "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13409      // sbc (immediate)
13410      {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13411       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
13412      // sbc (register)
13413      {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
13414       &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
13415      {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13416       &EmulateInstructionARM::EmulateSBCReg,
13417       "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
13418      // add (immediate, Thumb)
13419      {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13420       &EmulateInstructionARM::EmulateADDImmThumb,
13421       "adds|add<c> <Rd>,<Rn>,#<imm3>"},
13422      {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13423       &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
13424      {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13425       &EmulateInstructionARM::EmulateADDImmThumb,
13426       "add{s}<c>.w <Rd>,<Rn>,#<const>"},
13427      {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13428       &EmulateInstructionARM::EmulateADDImmThumb,
13429       "addw<c> <Rd>,<Rn>,#<imm12>"},
13430      // sub (immediate, Thumb)
13431      {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13432       &EmulateInstructionARM::EmulateSUBImmThumb,
13433       "subs|sub<c> <Rd>, <Rn> #imm3"},
13434      {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13435       &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13436      {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13437       &EmulateInstructionARM::EmulateSUBImmThumb,
13438       "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13439      {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13440       &EmulateInstructionARM::EmulateSUBImmThumb,
13441       "subw<c> <Rd>, <Rn>, #imm12"},
13442      // sub (sp minus immediate)
13443      {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13444       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13445      {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13446       &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13447      // sub (register)
13448      {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13449       &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13450      {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13451       &EmulateInstructionARM::EmulateSUBReg,
13452       "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13453      // teq (immediate)
13454      {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13455       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13456      // teq (register)
13457      {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13458       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13459      // tst (immediate)
13460      {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13461       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13462      // tst (register)
13463      {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13464       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13465      {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13466       &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13467
13468      // move from high register to high register
13469      {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13470       &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13471      // move from low register to low register
13472      {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13473       &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13474      // mov{s}<c>.w <Rd>, <Rm>
13475      {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13476       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13477      // move immediate
13478      {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13479       &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13480      {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13481       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13482      {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13483       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13484      // mvn (immediate)
13485      {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13486       &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13487      // mvn (register)
13488      {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13489       &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13490      {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13491       &EmulateInstructionARM::EmulateMVNReg,
13492       "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13493      // cmn (immediate)
13494      {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13495       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13496      // cmn (register)
13497      {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13498       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13499      {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13500       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13501      // cmp (immediate)
13502      {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13503       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13504      {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13505       &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13506      // cmp (register) (Rn and Rm both from r0-r7)
13507      {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13508       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13509      // cmp (register) (Rn and Rm not both from r0-r7)
13510      {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13511       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13512      {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13513       &EmulateInstructionARM::EmulateCMPReg,
13514       "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13515      // asr (immediate)
13516      {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13517       &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13518      {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13519       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13520      // asr (register)
13521      {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13522       &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13523      {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13524       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13525      // lsl (immediate)
13526      {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13527       &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13528      {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13529       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13530      // lsl (register)
13531      {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13532       &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13533      {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13534       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13535      // lsr (immediate)
13536      {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13537       &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13538      {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13539       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13540      // lsr (register)
13541      {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13542       &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13543      {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13544       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13545      // rrx is a special case encoding of ror (immediate)
13546      {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13547       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13548      // ror (immediate)
13549      {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13550       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13551      // ror (register)
13552      {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13553       &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13554      {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13555       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13556      // mul
13557      {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13558       &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13559      // mul
13560      {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13561       &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13562
13563      // subs pc, lr and related instructions
13564      {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13565       &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13566
13567      // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13568      // LDM.. Instructions in this table;
13569      // otherwise the wrong instructions will be selected.
13570
13571      {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13572       &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13573      {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13574       &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13575
13576      // Load instructions
13577      {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13578       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13579      {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13580       &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13581      {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13582       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13583      {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13584       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13585      {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13586       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13587      {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13588       &EmulateInstructionARM::EmulateLDRRtRnImm,
13589       "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13590      {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13591       &EmulateInstructionARM::EmulateLDRRtRnImm,
13592       "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13593      // Thumb2 PC-relative load into register
13594      {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13595       &EmulateInstructionARM::EmulateLDRRtPCRelative,
13596       "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13597      {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13598       &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13599      {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13600       &EmulateInstructionARM::EmulateLDRRegister,
13601       "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13602      {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13603       &EmulateInstructionARM::EmulateLDRBImmediate,
13604       "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13605      {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13606       &EmulateInstructionARM::EmulateLDRBImmediate,
13607       "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13608      {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13609       &EmulateInstructionARM::EmulateLDRBImmediate,
13610       "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13611      {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13612       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13613      {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13614       &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13615      {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13616       &EmulateInstructionARM::EmulateLDRBRegister,
13617       "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13618      {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13619       &EmulateInstructionARM::EmulateLDRHImmediate,
13620       "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13621      {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13622       &EmulateInstructionARM::EmulateLDRHImmediate,
13623       "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13624      {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13625       &EmulateInstructionARM::EmulateLDRHImmediate,
13626       "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13627      {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13628       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13629      {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13630       &EmulateInstructionARM::EmulateLDRHRegister,
13631       "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13632      {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13633       &EmulateInstructionARM::EmulateLDRHRegister,
13634       "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13635      {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13636       &EmulateInstructionARM::EmulateLDRSBImmediate,
13637       "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13638      {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13639       &EmulateInstructionARM::EmulateLDRSBImmediate,
13640       "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13641      {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13642       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13643      {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13644       &EmulateInstructionARM::EmulateLDRSBRegister,
13645       "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13646      {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13647       &EmulateInstructionARM::EmulateLDRSBRegister,
13648       "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13649      {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13650       &EmulateInstructionARM::EmulateLDRSHImmediate,
13651       "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13652      {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13653       &EmulateInstructionARM::EmulateLDRSHImmediate,
13654       "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13655      {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13656       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13657      {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13658       &EmulateInstructionARM::EmulateLDRSHRegister,
13659       "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13660      {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13661       &EmulateInstructionARM::EmulateLDRSHRegister,
13662       "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13663      {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13664       &EmulateInstructionARM::EmulateLDRDImmediate,
13665       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13666      {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13667       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13668      {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13669       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13670      {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13671       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13672      {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13673       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13674      {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13675       &EmulateInstructionARM::EmulateVLD1Multiple,
13676       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13677      {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13678       &EmulateInstructionARM::EmulateVLD1Single,
13679       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13680      {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13681       &EmulateInstructionARM::EmulateVLD1SingleAll,
13682       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13683
13684      // Store instructions
13685      {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13686       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13687      {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13688       &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13689      {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13690       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13691      {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13692       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13693      {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13694       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13695      {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13696       &EmulateInstructionARM::EmulateSTRThumb,
13697       "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13698      {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13699       &EmulateInstructionARM::EmulateSTRThumb,
13700       "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13701      {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13702       &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13703      {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13704       &EmulateInstructionARM::EmulateSTRRegister,
13705       "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13706      {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13707       &EmulateInstructionARM::EmulateSTRBThumb,
13708       "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13709      {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13710       &EmulateInstructionARM::EmulateSTRBThumb,
13711       "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13712      {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13713       &EmulateInstructionARM::EmulateSTRBThumb,
13714       "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13715      {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13716       &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13717      {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13718       &EmulateInstructionARM::EmulateSTRHRegister,
13719       "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13720      {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13721       &EmulateInstructionARM::EmulateSTREX,
13722       "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13723      {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13724       &EmulateInstructionARM::EmulateSTRDImm,
13725       "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13726      {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13727       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13728      {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13729       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13730      {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13731       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13732      {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13733       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13734      {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13735       &EmulateInstructionARM::EmulateVST1Multiple,
13736       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13737      {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13738       &EmulateInstructionARM::EmulateVST1Single,
13739       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13740
13741      // Other instructions
13742      {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13743       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13744      {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13745       &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13746      {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13747       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13748      {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13749       &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13750      {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13751       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13752      {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13753       &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13754      {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13755       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13756      {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13757       &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13758  };
13759
13760  const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13761  for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13762    if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13763        (g_thumb_opcodes[i].variants & arm_isa) != 0)
13764      return &g_thumb_opcodes[i];
13765  }
13766  return nullptr;
13767}
13768
13769bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13770  m_arch = arch;
13771  m_arm_isa = 0;
13772  const char *arch_cstr = arch.GetArchitectureName();
13773  if (arch_cstr) {
13774    if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13775      m_arm_isa = ARMv4T;
13776    else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13777      m_arm_isa = ARMv5TEJ;
13778    else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13779      m_arm_isa = ARMv5TE;
13780    else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13781      m_arm_isa = ARMv5T;
13782    else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13783      m_arm_isa = ARMv6K;
13784    else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13785      m_arm_isa = ARMv6T2;
13786    else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13787      m_arm_isa = ARMv7S;
13788    else if (0 == ::strcasecmp(arch_cstr, "arm"))
13789      m_arm_isa = ARMvAll;
13790    else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13791      m_arm_isa = ARMvAll;
13792    else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13793      m_arm_isa = ARMv4;
13794    else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13795      m_arm_isa = ARMv6;
13796    else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13797      m_arm_isa = ARMv7;
13798    else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13799      m_arm_isa = ARMv8;
13800  }
13801  return m_arm_isa != 0;
13802}
13803
13804bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13805                                           const Address &inst_addr,
13806                                           Target *target) {
13807  if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13808    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13809        m_arch.IsAlwaysThumbInstructions())
13810      m_opcode_mode = eModeThumb;
13811    else {
13812      AddressClass addr_class = inst_addr.GetAddressClass();
13813
13814      if ((addr_class == AddressClass::eCode) ||
13815          (addr_class == AddressClass::eUnknown))
13816        m_opcode_mode = eModeARM;
13817      else if (addr_class == AddressClass::eCodeAlternateISA)
13818        m_opcode_mode = eModeThumb;
13819      else
13820        return false;
13821    }
13822    if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13823      m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13824    else
13825      m_opcode_cpsr = CPSR_MODE_USR;
13826    return true;
13827  }
13828  return false;
13829}
13830
13831bool EmulateInstructionARM::ReadInstruction() {
13832  bool success = false;
13833  m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13834                                       LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13835  if (success) {
13836    addr_t pc =
13837        ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13838                             LLDB_INVALID_ADDRESS, &success);
13839    if (success) {
13840      Context read_inst_context;
13841      read_inst_context.type = eContextReadOpcode;
13842      read_inst_context.SetNoArgs();
13843
13844      if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13845        m_opcode_mode = eModeThumb;
13846        uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13847
13848        if (success) {
13849          if ((thumb_opcode & 0xe000) != 0xe000 ||
13850              ((thumb_opcode & 0x1800u) == 0)) {
13851            m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13852          } else {
13853            m_opcode.SetOpcode32(
13854                (thumb_opcode << 16) |
13855                    MemARead(read_inst_context, pc + 2, 2, 0, &success),
13856                GetByteOrder());
13857          }
13858        }
13859      } else {
13860        m_opcode_mode = eModeARM;
13861        m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13862                             GetByteOrder());
13863      }
13864
13865      if (!m_ignore_conditions) {
13866        // If we are not ignoreing the conditions then init the it session from
13867        // the current value of cpsr.
13868        uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13869                      Bits32(m_opcode_cpsr, 26, 25);
13870        if (it != 0)
13871          m_it_session.InitIT(it);
13872      }
13873    }
13874  }
13875  if (!success) {
13876    m_opcode_mode = eModeInvalid;
13877    m_addr = LLDB_INVALID_ADDRESS;
13878  }
13879  return success;
13880}
13881
13882uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13883
13884bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13885  // If we are ignoring conditions, then always return true. this allows us to
13886  // iterate over disassembly code and still emulate an instruction even if we
13887  // don't have all the right bits set in the CPSR register...
13888  if (m_ignore_conditions)
13889    return true;
13890
13891  const uint32_t cond = CurrentCond(opcode);
13892  if (cond == UINT32_MAX)
13893    return false;
13894
13895  bool result = false;
13896  switch (UnsignedBits(cond, 3, 1)) {
13897  case 0:
13898    if (m_opcode_cpsr == 0)
13899      result = true;
13900    else
13901      result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13902    break;
13903  case 1:
13904    if (m_opcode_cpsr == 0)
13905      result = true;
13906    else
13907      result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13908    break;
13909  case 2:
13910    if (m_opcode_cpsr == 0)
13911      result = true;
13912    else
13913      result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13914    break;
13915  case 3:
13916    if (m_opcode_cpsr == 0)
13917      result = true;
13918    else
13919      result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13920    break;
13921  case 4:
13922    if (m_opcode_cpsr == 0)
13923      result = true;
13924    else
13925      result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13926               ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13927    break;
13928  case 5:
13929    if (m_opcode_cpsr == 0)
13930      result = true;
13931    else {
13932      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13933      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13934      result = n == v;
13935    }
13936    break;
13937  case 6:
13938    if (m_opcode_cpsr == 0)
13939      result = true;
13940    else {
13941      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13942      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13943      result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13944    }
13945    break;
13946  case 7:
13947    // Always execute (cond == 0b1110, or the special 0b1111 which gives
13948    // opcodes different meanings, but always means execution happens.
13949    return true;
13950  }
13951
13952  if (cond & 1)
13953    result = !result;
13954  return result;
13955}
13956
13957uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13958  switch (m_opcode_mode) {
13959  case eModeInvalid:
13960    break;
13961
13962  case eModeARM:
13963    return UnsignedBits(opcode, 31, 28);
13964
13965  case eModeThumb:
13966    // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13967    // 'cond' field of the encoding.
13968    {
13969      const uint32_t byte_size = m_opcode.GetByteSize();
13970      if (byte_size == 2) {
13971        if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13972          return Bits32(opcode, 11, 8);
13973      } else if (byte_size == 4) {
13974        if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13975            Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13976          return Bits32(opcode, 25, 22);
13977        }
13978      } else
13979        // We have an invalid thumb instruction, let's bail out.
13980        break;
13981
13982      return m_it_session.GetCond();
13983    }
13984  }
13985  return UINT32_MAX; // Return invalid value
13986}
13987
13988bool EmulateInstructionARM::InITBlock() {
13989  return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13990}
13991
13992bool EmulateInstructionARM::LastInITBlock() {
13993  return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13994}
13995
13996bool EmulateInstructionARM::BadMode(uint32_t mode) {
13997
13998  switch (mode) {
13999  case 16:
14000    return false; // '10000'
14001  case 17:
14002    return false; // '10001'
14003  case 18:
14004    return false; // '10010'
14005  case 19:
14006    return false; // '10011'
14007  case 22:
14008    return false; // '10110'
14009  case 23:
14010    return false; // '10111'
14011  case 27:
14012    return false; // '11011'
14013  case 31:
14014    return false; // '11111'
14015  default:
14016    return true;
14017  }
14018  return true;
14019}
14020
14021bool EmulateInstructionARM::CurrentModeIsPrivileged() {
14022  uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
14023
14024  if (BadMode(mode))
14025    return false;
14026
14027  if (mode == 16)
14028    return false;
14029
14030  return true;
14031}
14032
14033void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
14034                                             bool affect_execstate) {
14035  bool privileged = CurrentModeIsPrivileged();
14036
14037  uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
14038
14039  if (BitIsSet(bytemask, 3)) {
14040    tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
14041    if (affect_execstate)
14042      tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
14043  }
14044
14045  if (BitIsSet(bytemask, 2)) {
14046    tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
14047  }
14048
14049  if (BitIsSet(bytemask, 1)) {
14050    if (affect_execstate)
14051      tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
14052    tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
14053    if (privileged)
14054      tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
14055  }
14056
14057  if (BitIsSet(bytemask, 0)) {
14058    if (privileged)
14059      tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
14060    if (affect_execstate)
14061      tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
14062    if (privileged)
14063      tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
14064  }
14065
14066  m_opcode_cpsr = tmp_cpsr;
14067}
14068
14069bool EmulateInstructionARM::BranchWritePC(const Context &context,
14070                                          uint32_t addr) {
14071  addr_t target;
14072
14073  // Check the current instruction set.
14074  if (CurrentInstrSet() == eModeARM)
14075    target = addr & 0xfffffffc;
14076  else
14077    target = addr & 0xfffffffe;
14078
14079  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14080                               LLDB_REGNUM_GENERIC_PC, target);
14081}
14082
14083// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
14084// inspecting addr.
14085bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
14086  addr_t target;
14087  // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
14088  // we want to record it and issue a WriteRegister callback so the clients can
14089  // track the mode changes accordingly.
14090  bool cpsr_changed = false;
14091
14092  if (BitIsSet(addr, 0)) {
14093    if (CurrentInstrSet() != eModeThumb) {
14094      SelectInstrSet(eModeThumb);
14095      cpsr_changed = true;
14096    }
14097    target = addr & 0xfffffffe;
14098    context.SetISA(eModeThumb);
14099  } else if (BitIsClear(addr, 1)) {
14100    if (CurrentInstrSet() != eModeARM) {
14101      SelectInstrSet(eModeARM);
14102      cpsr_changed = true;
14103    }
14104    target = addr & 0xfffffffc;
14105    context.SetISA(eModeARM);
14106  } else
14107    return false; // address<1:0> == '10' => UNPREDICTABLE
14108
14109  if (cpsr_changed) {
14110    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14111                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14112      return false;
14113  }
14114  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
14115                               LLDB_REGNUM_GENERIC_PC, target);
14116}
14117
14118// Dispatches to either BXWritePC or BranchWritePC based on architecture
14119// versions.
14120bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
14121  if (ArchVersion() >= ARMv5T)
14122    return BXWritePC(context, addr);
14123  else
14124    return BranchWritePC((const Context)context, addr);
14125}
14126
14127// Dispatches to either BXWritePC or BranchWritePC based on architecture
14128// versions and current instruction set.
14129bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
14130  if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
14131    return BXWritePC(context, addr);
14132  else
14133    return BranchWritePC((const Context)context, addr);
14134}
14135
14136EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
14137  return m_opcode_mode;
14138}
14139
14140// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
14141// ReadInstruction() is performed.  This function has a side effect of updating
14142// the m_new_inst_cpsr member variable if necessary.
14143bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
14144  m_new_inst_cpsr = m_opcode_cpsr;
14145  switch (arm_or_thumb) {
14146  default:
14147    return false;
14148  case eModeARM:
14149    // Clear the T bit.
14150    m_new_inst_cpsr &= ~MASK_CPSR_T;
14151    break;
14152  case eModeThumb:
14153    // Set the T bit.
14154    m_new_inst_cpsr |= MASK_CPSR_T;
14155    break;
14156  }
14157  return true;
14158}
14159
14160// This function returns TRUE if the processor currently provides support for
14161// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
14162// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
14163bool EmulateInstructionARM::UnalignedSupport() {
14164  return (ArchVersion() >= ARMv7);
14165}
14166
14167// The main addition and subtraction instructions can produce status
14168// information about both unsigned carry and signed overflow conditions.  This
14169// status information can be used to synthesize multi-word additions and
14170// subtractions.
14171EmulateInstructionARM::AddWithCarryResult
14172EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
14173  uint32_t result;
14174  uint8_t carry_out;
14175  uint8_t overflow;
14176
14177  uint64_t unsigned_sum = x + y + carry_in;
14178  int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
14179
14180  result = UnsignedBits(unsigned_sum, 31, 0);
14181  //    carry_out = (result == unsigned_sum ? 0 : 1);
14182  overflow = ((int32_t)result == signed_sum ? 0 : 1);
14183
14184  if (carry_in)
14185    carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
14186  else
14187    carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
14188
14189  AddWithCarryResult res = {result, carry_out, overflow};
14190  return res;
14191}
14192
14193uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
14194  lldb::RegisterKind reg_kind;
14195  uint32_t reg_num;
14196  switch (num) {
14197  case SP_REG:
14198    reg_kind = eRegisterKindGeneric;
14199    reg_num = LLDB_REGNUM_GENERIC_SP;
14200    break;
14201  case LR_REG:
14202    reg_kind = eRegisterKindGeneric;
14203    reg_num = LLDB_REGNUM_GENERIC_RA;
14204    break;
14205  case PC_REG:
14206    reg_kind = eRegisterKindGeneric;
14207    reg_num = LLDB_REGNUM_GENERIC_PC;
14208    break;
14209  default:
14210    if (num < SP_REG) {
14211      reg_kind = eRegisterKindDWARF;
14212      reg_num = dwarf_r0 + num;
14213    } else {
14214      // assert(0 && "Invalid register number");
14215      *success = false;
14216      return UINT32_MAX;
14217    }
14218    break;
14219  }
14220
14221  // Read our register.
14222  uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
14223
14224  // When executing an ARM instruction , PC reads as the address of the current
14225  // instruction plus 8. When executing a Thumb instruction , PC reads as the
14226  // address of the current instruction plus 4.
14227  if (num == 15) {
14228    if (CurrentInstrSet() == eModeARM)
14229      val += 8;
14230    else
14231      val += 4;
14232  }
14233
14234  return val;
14235}
14236
14237// Write the result to the ARM core register Rd, and optionally update the
14238// condition flags based on the result.
14239//
14240// This helper method tries to encapsulate the following pseudocode from the
14241// ARM Architecture Reference Manual:
14242//
14243// if d == 15 then         // Can only occur for encoding A1
14244//     ALUWritePC(result); // setflags is always FALSE here
14245// else
14246//     R[d] = result;
14247//     if setflags then
14248//         APSR.N = result<31>;
14249//         APSR.Z = IsZeroBit(result);
14250//         APSR.C = carry;
14251//         // APSR.V unchanged
14252//
14253// In the above case, the API client does not pass in the overflow arg, which
14254// defaults to ~0u.
14255bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
14256    Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
14257    const uint32_t carry, const uint32_t overflow) {
14258  if (Rd == 15) {
14259    if (!ALUWritePC(context, result))
14260      return false;
14261  } else {
14262    lldb::RegisterKind reg_kind;
14263    uint32_t reg_num;
14264    switch (Rd) {
14265    case SP_REG:
14266      reg_kind = eRegisterKindGeneric;
14267      reg_num = LLDB_REGNUM_GENERIC_SP;
14268      break;
14269    case LR_REG:
14270      reg_kind = eRegisterKindGeneric;
14271      reg_num = LLDB_REGNUM_GENERIC_RA;
14272      break;
14273    default:
14274      reg_kind = eRegisterKindDWARF;
14275      reg_num = dwarf_r0 + Rd;
14276    }
14277    if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
14278      return false;
14279    if (setflags)
14280      return WriteFlags(context, result, carry, overflow);
14281  }
14282  return true;
14283}
14284
14285// This helper method tries to encapsulate the following pseudocode from the
14286// ARM Architecture Reference Manual:
14287//
14288// APSR.N = result<31>;
14289// APSR.Z = IsZeroBit(result);
14290// APSR.C = carry;
14291// APSR.V = overflow
14292//
14293// Default arguments can be specified for carry and overflow parameters, which
14294// means not to update the respective flags.
14295bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
14296                                       const uint32_t carry,
14297                                       const uint32_t overflow) {
14298  m_new_inst_cpsr = m_opcode_cpsr;
14299  SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
14300  SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
14301  if (carry != ~0u)
14302    SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
14303  if (overflow != ~0u)
14304    SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
14305  if (m_new_inst_cpsr != m_opcode_cpsr) {
14306    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
14307                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
14308      return false;
14309  }
14310  return true;
14311}
14312
14313bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
14314  ARMOpcode *opcode_data = nullptr;
14315
14316  if (m_opcode_mode == eModeThumb)
14317    opcode_data =
14318        GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14319  else if (m_opcode_mode == eModeARM)
14320    opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
14321
14322  const bool auto_advance_pc =
14323      evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
14324  m_ignore_conditions =
14325      evaluate_options & eEmulateInstructionOptionIgnoreConditions;
14326
14327  bool success = false;
14328  if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
14329    m_opcode_cpsr =
14330        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
14331  }
14332
14333  // Only return false if we are unable to read the CPSR if we care about
14334  // conditions
14335  if (!success && !m_ignore_conditions)
14336    return false;
14337
14338  uint32_t orig_pc_value = 0;
14339  if (auto_advance_pc) {
14340    orig_pc_value =
14341        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14342    if (!success)
14343      return false;
14344  }
14345
14346  // Call the Emulate... function if we managed to decode the opcode.
14347  if (opcode_data) {
14348    success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
14349                                             opcode_data->encoding);
14350    if (!success)
14351      return false;
14352  }
14353
14354  // Advance the ITSTATE bits to their values for the next instruction if we
14355  // haven't just executed an IT instruction what initialized it.
14356  if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
14357      (opcode_data == nullptr ||
14358       opcode_data->callback != &EmulateInstructionARM::EmulateIT))
14359    m_it_session.ITAdvance();
14360
14361  if (auto_advance_pc) {
14362    uint32_t after_pc_value =
14363        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
14364    if (!success)
14365      return false;
14366
14367    if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
14368      after_pc_value += m_opcode.GetByteSize();
14369
14370      EmulateInstruction::Context context;
14371      context.type = eContextAdvancePC;
14372      context.SetNoArgs();
14373      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
14374                                 after_pc_value))
14375        return false;
14376    }
14377  }
14378  return true;
14379}
14380
14381EmulateInstruction::InstructionCondition
14382EmulateInstructionARM::GetInstructionCondition() {
14383  const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
14384  if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
14385    return EmulateInstruction::UnconditionalCondition;
14386  return cond;
14387}
14388
14389bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
14390                                          OptionValueDictionary *test_data) {
14391  if (!test_data) {
14392    out_stream->Printf("TestEmulation: Missing test data.\n");
14393    return false;
14394  }
14395
14396  static ConstString opcode_key("opcode");
14397  static ConstString before_key("before_state");
14398  static ConstString after_key("after_state");
14399
14400  OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
14401
14402  uint32_t test_opcode;
14403  if ((value_sp.get() == nullptr) ||
14404      (value_sp->GetType() != OptionValue::eTypeUInt64)) {
14405    out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
14406    return false;
14407  }
14408  test_opcode = value_sp->GetUInt64Value();
14409
14410  if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
14411      arch.IsAlwaysThumbInstructions()) {
14412    m_opcode_mode = eModeThumb;
14413    if (test_opcode < 0x10000)
14414      m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14415    else
14416      m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14417  } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14418    m_opcode_mode = eModeARM;
14419    m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14420  } else {
14421    out_stream->Printf("TestEmulation:  Invalid arch.\n");
14422    return false;
14423  }
14424
14425  EmulationStateARM before_state;
14426  EmulationStateARM after_state;
14427
14428  value_sp = test_data->GetValueForKey(before_key);
14429  if ((value_sp.get() == nullptr) ||
14430      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14431    out_stream->Printf("TestEmulation:  Failed to find 'before' state.\n");
14432    return false;
14433  }
14434
14435  OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14436  if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14437    out_stream->Printf("TestEmulation:  Failed loading 'before' state.\n");
14438    return false;
14439  }
14440
14441  value_sp = test_data->GetValueForKey(after_key);
14442  if ((value_sp.get() == nullptr) ||
14443      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14444    out_stream->Printf("TestEmulation:  Failed to find 'after' state.\n");
14445    return false;
14446  }
14447
14448  state_dictionary = value_sp->GetAsDictionary();
14449  if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14450    out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14451    return false;
14452  }
14453
14454  SetBaton((void *)&before_state);
14455  SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14456               &EmulationStateARM::WritePseudoMemory,
14457               &EmulationStateARM::ReadPseudoRegister,
14458               &EmulationStateARM::WritePseudoRegister);
14459
14460  bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14461  if (!success) {
14462    out_stream->Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14463    return false;
14464  }
14465
14466  success = before_state.CompareState(after_state);
14467  if (!success)
14468    out_stream->Printf(
14469        "TestEmulation:  'before' and 'after' states do not match.\n");
14470
14471  return success;
14472}
14473//
14474//
14475// const char *
14476// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14477//{
14478//    if (reg_kind == eRegisterKindGeneric)
14479//    {
14480//        switch (reg_num)
14481//        {
14482//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14483//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14484//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14485//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14486//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14487//        default: return NULL;
14488//        }
14489//    }
14490//    else if (reg_kind == eRegisterKindDWARF)
14491//    {
14492//        return GetARMDWARFRegisterName (reg_num);
14493//    }
14494//    return NULL;
14495//}
14496//
14497bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14498  unwind_plan.Clear();
14499  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14500
14501  UnwindPlan::RowSP row(new UnwindPlan::Row);
14502
14503  // Our previous Call Frame Address is the stack pointer
14504  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14505
14506  unwind_plan.AppendRow(row);
14507  unwind_plan.SetSourceName("EmulateInstructionARM");
14508  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14509  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14510  unwind_plan.SetReturnAddressRegister(dwarf_lr);
14511  return true;
14512}
14513