EmulateInstructionARM.cpp revision 314564
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdlib.h>
11
12#include "EmulateInstructionARM.h"
13#include "EmulationStateARM.h"
14#include "lldb/Core/Address.h"
15#include "lldb/Core/ArchSpec.h"
16#include "lldb/Core/ConstString.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/Stream.h"
19#include "lldb/Host/PosixApi.h"
20#include "lldb/Interpreter/OptionValueArray.h"
21#include "lldb/Interpreter/OptionValueDictionary.h"
22#include "lldb/Symbol/UnwindPlan.h"
23
24#include "Plugins/Process/Utility/ARMDefines.h"
25#include "Plugins/Process/Utility/ARMUtils.h"
26#include "Utility/ARM_DWARF_Registers.h"
27
28#include "llvm/ADT/STLExtras.h"
29#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
30                                     // and countTrailingZeros function
31
32using namespace lldb;
33using namespace lldb_private;
34
35// Convenient macro definitions.
36#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
37#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
38
39#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
40
41//----------------------------------------------------------------------
42//
43// ITSession implementation
44//
45//----------------------------------------------------------------------
46
47// A8.6.50
48// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
49static uint32_t CountITSize(uint32_t ITMask) {
50  // First count the trailing zeros of the IT mask.
51  uint32_t TZ = llvm::countTrailingZeros(ITMask);
52  if (TZ > 3) {
53#ifdef LLDB_CONFIGURATION_DEBUG
54    printf("Encoding error: IT Mask '0000'\n");
55#endif
56    return 0;
57  }
58  return (4 - TZ);
59}
60
61// Init ITState.  Note that at least one bit is always 1 in mask.
62bool ITSession::InitIT(uint32_t bits7_0) {
63  ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
64  if (ITCounter == 0)
65    return false;
66
67  // A8.6.50 IT
68  unsigned short FirstCond = Bits32(bits7_0, 7, 4);
69  if (FirstCond == 0xF) {
70#ifdef LLDB_CONFIGURATION_DEBUG
71    printf("Encoding error: IT FirstCond '1111'\n");
72#endif
73    return false;
74  }
75  if (FirstCond == 0xE && ITCounter != 1) {
76#ifdef LLDB_CONFIGURATION_DEBUG
77    printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
78#endif
79    return false;
80  }
81
82  ITState = bits7_0;
83  return true;
84}
85
86// Update ITState if necessary.
87void ITSession::ITAdvance() {
88  // assert(ITCounter);
89  --ITCounter;
90  if (ITCounter == 0)
91    ITState = 0;
92  else {
93    unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
94    SetBits32(ITState, 4, 0, NewITState4_0);
95  }
96}
97
98// Return true if we're inside an IT Block.
99bool ITSession::InITBlock() { return ITCounter != 0; }
100
101// Return true if we're the last instruction inside an IT Block.
102bool ITSession::LastInITBlock() { return ITCounter == 1; }
103
104// Get condition bits for the current thumb instruction.
105uint32_t ITSession::GetCond() {
106  if (InITBlock())
107    return Bits32(ITState, 7, 4);
108  else
109    return COND_AL;
110}
111
112// ARM constants used during decoding
113#define REG_RD 0
114#define LDM_REGLIST 1
115#define SP_REG 13
116#define LR_REG 14
117#define PC_REG 15
118#define PC_REGLIST_BIT 0x8000
119
120#define ARMv4 (1u << 0)
121#define ARMv4T (1u << 1)
122#define ARMv5T (1u << 2)
123#define ARMv5TE (1u << 3)
124#define ARMv5TEJ (1u << 4)
125#define ARMv6 (1u << 5)
126#define ARMv6K (1u << 6)
127#define ARMv6T2 (1u << 7)
128#define ARMv7 (1u << 8)
129#define ARMv7S (1u << 9)
130#define ARMv8 (1u << 10)
131#define ARMvAll (0xffffffffu)
132
133#define ARMV4T_ABOVE                                                           \
134  (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 |   \
135   ARMv7S | ARMv8)
136#define ARMV5_ABOVE                                                            \
137  (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S |   \
138   ARMv8)
139#define ARMV5TE_ABOVE                                                          \
140  (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
141#define ARMV5J_ABOVE                                                           \
142  (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
143#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
144#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
145#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
146
147#define No_VFP 0
148#define VFPv1 (1u << 1)
149#define VFPv2 (1u << 2)
150#define VFPv3 (1u << 3)
151#define AdvancedSIMD (1u << 4)
152
153#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
154#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
155#define VFPv2v3 (VFPv2 | VFPv3)
156
157//----------------------------------------------------------------------
158//
159// EmulateInstructionARM implementation
160//
161//----------------------------------------------------------------------
162
163void EmulateInstructionARM::Initialize() {
164  PluginManager::RegisterPlugin(GetPluginNameStatic(),
165                                GetPluginDescriptionStatic(), CreateInstance);
166}
167
168void EmulateInstructionARM::Terminate() {
169  PluginManager::UnregisterPlugin(CreateInstance);
170}
171
172ConstString EmulateInstructionARM::GetPluginNameStatic() {
173  static ConstString g_name("arm");
174  return g_name;
175}
176
177const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
178  return "Emulate instructions for the ARM architecture.";
179}
180
181EmulateInstruction *
182EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
183                                      InstructionType inst_type) {
184  if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
185          inst_type)) {
186    if (arch.GetTriple().getArch() == llvm::Triple::arm) {
187      std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
188          new EmulateInstructionARM(arch));
189
190      if (emulate_insn_ap.get())
191        return emulate_insn_ap.release();
192    } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
193      std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
194          new EmulateInstructionARM(arch));
195
196      if (emulate_insn_ap.get())
197        return emulate_insn_ap.release();
198    }
199  }
200
201  return NULL;
202}
203
204bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
205  if (arch.GetTriple().getArch() == llvm::Triple::arm)
206    return true;
207  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
208    return true;
209
210  return false;
211}
212
213// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for
214// many ARM instructions.
215bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
216  EmulateInstruction::Context context;
217  context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
218  context.SetNoArgs();
219
220  uint32_t random_data = rand();
221  const uint32_t addr_byte_size = GetAddressByteSize();
222
223  if (!MemAWrite(context, address, random_data, addr_byte_size))
224    return false;
225
226  return true;
227}
228
229// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM
230// instructions.
231bool EmulateInstructionARM::WriteBits32Unknown(int n) {
232  EmulateInstruction::Context context;
233  context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
234  context.SetNoArgs();
235
236  bool success;
237  uint32_t data =
238      ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
239
240  if (!success)
241    return false;
242
243  if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
244    return false;
245
246  return true;
247}
248
249bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
250                                            uint32_t reg_num,
251                                            RegisterInfo &reg_info) {
252  if (reg_kind == eRegisterKindGeneric) {
253    switch (reg_num) {
254    case LLDB_REGNUM_GENERIC_PC:
255      reg_kind = eRegisterKindDWARF;
256      reg_num = dwarf_pc;
257      break;
258    case LLDB_REGNUM_GENERIC_SP:
259      reg_kind = eRegisterKindDWARF;
260      reg_num = dwarf_sp;
261      break;
262    case LLDB_REGNUM_GENERIC_FP:
263      reg_kind = eRegisterKindDWARF;
264      reg_num = dwarf_r7;
265      break;
266    case LLDB_REGNUM_GENERIC_RA:
267      reg_kind = eRegisterKindDWARF;
268      reg_num = dwarf_lr;
269      break;
270    case LLDB_REGNUM_GENERIC_FLAGS:
271      reg_kind = eRegisterKindDWARF;
272      reg_num = dwarf_cpsr;
273      break;
274    default:
275      return false;
276    }
277  }
278
279  if (reg_kind == eRegisterKindDWARF)
280    return GetARMDWARFRegisterInfo(reg_num, reg_info);
281  return false;
282}
283
284uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
285  if (m_arch.GetTriple().isAndroid())
286    return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
287  bool is_apple = false;
288  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
289    is_apple = true;
290  switch (m_arch.GetTriple().getOS()) {
291  case llvm::Triple::Darwin:
292  case llvm::Triple::MacOSX:
293  case llvm::Triple::IOS:
294  case llvm::Triple::TvOS:
295  case llvm::Triple::WatchOS:
296    is_apple = true;
297    break;
298  default:
299    break;
300  }
301
302  /* On Apple iOS et al, the frame pointer register is always r7.
303   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
304   */
305
306  uint32_t fp_regnum = 11;
307
308  if (is_apple)
309    fp_regnum = 7;
310
311  if (m_opcode_mode == eModeThumb)
312    fp_regnum = 7;
313
314  return fp_regnum;
315}
316
317uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
318  bool is_apple = false;
319  if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
320    is_apple = true;
321  switch (m_arch.GetTriple().getOS()) {
322  case llvm::Triple::Darwin:
323  case llvm::Triple::MacOSX:
324  case llvm::Triple::IOS:
325    is_apple = true;
326    break;
327  default:
328    break;
329  }
330
331  /* On Apple iOS et al, the frame pointer register is always r7.
332   * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
333   */
334
335  uint32_t fp_regnum = dwarf_r11;
336
337  if (is_apple)
338    fp_regnum = dwarf_r7;
339
340  if (m_opcode_mode == eModeThumb)
341    fp_regnum = dwarf_r7;
342
343  return fp_regnum;
344}
345
346// Push Multiple Registers stores multiple registers to the stack, storing to
347// consecutive memory locations ending just below the address in SP, and updates
348// SP to point to the start of the stored data.
349bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
350                                        const ARMEncoding encoding) {
351#if 0
352    // ARM pseudo code...
353    if (ConditionPassed())
354    {
355        EncodingSpecificOperations();
356        NullCheckIfThumbEE(13);
357        address = SP - 4*BitCount(registers);
358
359        for (i = 0 to 14)
360        {
361            if (registers<i> == '1')
362            {
363                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
364                    MemA[address,4] = bits(32) UNKNOWN;
365                else
366                    MemA[address,4] = R[i];
367                address = address + 4;
368            }
369        }
370
371        if (registers<15> == '1') // Only possible for encoding A1 or A2
372            MemA[address,4] = PCStoreValue();
373
374        SP = SP - 4*BitCount(registers);
375    }
376#endif
377
378  bool success = false;
379  if (ConditionPassed(opcode)) {
380    const uint32_t addr_byte_size = GetAddressByteSize();
381    const addr_t sp = ReadCoreReg(SP_REG, &success);
382    if (!success)
383      return false;
384    uint32_t registers = 0;
385    uint32_t Rt; // the source register
386    switch (encoding) {
387    case eEncodingT1:
388      registers = Bits32(opcode, 7, 0);
389      // The M bit represents LR.
390      if (Bit32(opcode, 8))
391        registers |= (1u << 14);
392      // if BitCount(registers) < 1 then UNPREDICTABLE;
393      if (BitCount(registers) < 1)
394        return false;
395      break;
396    case eEncodingT2:
397      // Ignore bits 15 & 13.
398      registers = Bits32(opcode, 15, 0) & ~0xa000;
399      // if BitCount(registers) < 2 then UNPREDICTABLE;
400      if (BitCount(registers) < 2)
401        return false;
402      break;
403    case eEncodingT3:
404      Rt = Bits32(opcode, 15, 12);
405      // if BadReg(t) then UNPREDICTABLE;
406      if (BadReg(Rt))
407        return false;
408      registers = (1u << Rt);
409      break;
410    case eEncodingA1:
411      registers = Bits32(opcode, 15, 0);
412      // Instead of return false, let's handle the following case as well,
413      // which amounts to pushing one reg onto the full descending stacks.
414      // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
415      break;
416    case eEncodingA2:
417      Rt = Bits32(opcode, 15, 12);
418      // if t == 13 then UNPREDICTABLE;
419      if (Rt == dwarf_sp)
420        return false;
421      registers = (1u << Rt);
422      break;
423    default:
424      return false;
425    }
426    addr_t sp_offset = addr_byte_size * BitCount(registers);
427    addr_t addr = sp - sp_offset;
428    uint32_t i;
429
430    EmulateInstruction::Context context;
431    context.type = EmulateInstruction::eContextPushRegisterOnStack;
432    RegisterInfo reg_info;
433    RegisterInfo sp_reg;
434    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
435    for (i = 0; i < 15; ++i) {
436      if (BitIsSet(registers, i)) {
437        GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
438        context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
439        uint32_t reg_value = ReadCoreReg(i, &success);
440        if (!success)
441          return false;
442        if (!MemAWrite(context, addr, reg_value, addr_byte_size))
443          return false;
444        addr += addr_byte_size;
445      }
446    }
447
448    if (BitIsSet(registers, 15)) {
449      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
450      context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
451      const uint32_t pc = ReadCoreReg(PC_REG, &success);
452      if (!success)
453        return false;
454      if (!MemAWrite(context, addr, pc, addr_byte_size))
455        return false;
456    }
457
458    context.type = EmulateInstruction::eContextAdjustStackPointer;
459    context.SetImmediateSigned(-sp_offset);
460
461    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
462                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
463      return false;
464  }
465  return true;
466}
467
468// Pop Multiple Registers loads multiple registers from the stack, loading from
469// consecutive memory locations staring at the address in SP, and updates
470// SP to point just above the loaded data.
471bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
472                                       const ARMEncoding encoding) {
473#if 0
474    // ARM pseudo code...
475    if (ConditionPassed())
476    {
477        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
478        address = SP;
479        for i = 0 to 14
480            if registers<i> == '1' then
481                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
482        if registers<15> == '1' then
483            if UnalignedAllowed then
484                LoadWritePC(MemU[address,4]);
485            else
486                LoadWritePC(MemA[address,4]);
487        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
488        if registers<13> == '1' then SP = bits(32) UNKNOWN;
489    }
490#endif
491
492  bool success = false;
493
494  if (ConditionPassed(opcode)) {
495    const uint32_t addr_byte_size = GetAddressByteSize();
496    const addr_t sp = ReadCoreReg(SP_REG, &success);
497    if (!success)
498      return false;
499    uint32_t registers = 0;
500    uint32_t Rt; // the destination register
501    switch (encoding) {
502    case eEncodingT1:
503      registers = Bits32(opcode, 7, 0);
504      // The P bit represents PC.
505      if (Bit32(opcode, 8))
506        registers |= (1u << 15);
507      // if BitCount(registers) < 1 then UNPREDICTABLE;
508      if (BitCount(registers) < 1)
509        return false;
510      break;
511    case eEncodingT2:
512      // Ignore bit 13.
513      registers = Bits32(opcode, 15, 0) & ~0x2000;
514      // if BitCount(registers) < 2 || (P == '1' && M == '1') then
515      // UNPREDICTABLE;
516      if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
517        return false;
518      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
519      // UNPREDICTABLE;
520      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
521        return false;
522      break;
523    case eEncodingT3:
524      Rt = Bits32(opcode, 15, 12);
525      // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
526      // UNPREDICTABLE;
527      if (Rt == 13)
528        return false;
529      if (Rt == 15 && InITBlock() && !LastInITBlock())
530        return false;
531      registers = (1u << Rt);
532      break;
533    case eEncodingA1:
534      registers = Bits32(opcode, 15, 0);
535      // Instead of return false, let's handle the following case as well,
536      // which amounts to popping one reg from the full descending stacks.
537      // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
538
539      // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
540      if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
541        return false;
542      break;
543    case eEncodingA2:
544      Rt = Bits32(opcode, 15, 12);
545      // if t == 13 then UNPREDICTABLE;
546      if (Rt == dwarf_sp)
547        return false;
548      registers = (1u << Rt);
549      break;
550    default:
551      return false;
552    }
553    addr_t sp_offset = addr_byte_size * BitCount(registers);
554    addr_t addr = sp;
555    uint32_t i, data;
556
557    EmulateInstruction::Context context;
558    context.type = EmulateInstruction::eContextPopRegisterOffStack;
559
560    RegisterInfo sp_reg;
561    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
562
563    for (i = 0; i < 15; ++i) {
564      if (BitIsSet(registers, i)) {
565        context.SetAddress(addr);
566        data = MemARead(context, addr, 4, 0, &success);
567        if (!success)
568          return false;
569        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
570                                   data))
571          return false;
572        addr += addr_byte_size;
573      }
574    }
575
576    if (BitIsSet(registers, 15)) {
577      context.SetRegisterPlusOffset(sp_reg, addr - sp);
578      data = MemARead(context, addr, 4, 0, &success);
579      if (!success)
580        return false;
581      // In ARMv5T and above, this is an interworking branch.
582      if (!LoadWritePC(context, data))
583        return false;
584      // addr += addr_byte_size;
585    }
586
587    context.type = EmulateInstruction::eContextAdjustStackPointer;
588    context.SetImmediateSigned(sp_offset);
589
590    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
591                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
592      return false;
593  }
594  return true;
595}
596
597// Set r7 or ip to point to saved value residing within the stack.
598// ADD (SP plus immediate)
599bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
600                                              const ARMEncoding encoding) {
601#if 0
602    // ARM pseudo code...
603    if (ConditionPassed())
604    {
605        EncodingSpecificOperations();
606        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
607        if d == 15 then
608           ALUWritePC(result); // setflags is always FALSE here
609        else
610            R[d] = result;
611            if setflags then
612                APSR.N = result<31>;
613                APSR.Z = IsZeroBit(result);
614                APSR.C = carry;
615                APSR.V = overflow;
616    }
617#endif
618
619  bool success = false;
620
621  if (ConditionPassed(opcode)) {
622    const addr_t sp = ReadCoreReg(SP_REG, &success);
623    if (!success)
624      return false;
625    uint32_t Rd; // the destination register
626    uint32_t imm32;
627    switch (encoding) {
628    case eEncodingT1:
629      Rd = 7;
630      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
631      break;
632    case eEncodingA1:
633      Rd = Bits32(opcode, 15, 12);
634      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
635      break;
636    default:
637      return false;
638    }
639    addr_t sp_offset = imm32;
640    addr_t addr = sp + sp_offset; // a pointer to the stack area
641
642    EmulateInstruction::Context context;
643    if (Rd == GetFramePointerRegisterNumber())
644      context.type = eContextSetFramePointer;
645    else
646      context.type = EmulateInstruction::eContextRegisterPlusOffset;
647    RegisterInfo sp_reg;
648    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
649    context.SetRegisterPlusOffset(sp_reg, sp_offset);
650
651    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
652                               addr))
653      return false;
654  }
655  return true;
656}
657
658// Set r7 or ip to the current stack pointer.
659// MOV (register)
660bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
661                                           const ARMEncoding encoding) {
662#if 0
663    // ARM pseudo code...
664    if (ConditionPassed())
665    {
666        EncodingSpecificOperations();
667        result = R[m];
668        if d == 15 then
669            ALUWritePC(result); // setflags is always FALSE here
670        else
671            R[d] = result;
672            if setflags then
673                APSR.N = result<31>;
674                APSR.Z = IsZeroBit(result);
675                // APSR.C unchanged
676                // APSR.V unchanged
677    }
678#endif
679
680  bool success = false;
681
682  if (ConditionPassed(opcode)) {
683    const addr_t sp = ReadCoreReg(SP_REG, &success);
684    if (!success)
685      return false;
686    uint32_t Rd; // the destination register
687    switch (encoding) {
688    case eEncodingT1:
689      Rd = 7;
690      break;
691    case eEncodingA1:
692      Rd = 12;
693      break;
694    default:
695      return false;
696    }
697
698    EmulateInstruction::Context context;
699    if (Rd == GetFramePointerRegisterNumber())
700      context.type = EmulateInstruction::eContextSetFramePointer;
701    else
702      context.type = EmulateInstruction::eContextRegisterPlusOffset;
703    RegisterInfo sp_reg;
704    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
705    context.SetRegisterPlusOffset(sp_reg, 0);
706
707    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
708      return false;
709  }
710  return true;
711}
712
713// Move from high register (r8-r15) to low register (r0-r7).
714// MOV (register)
715bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
716                                              const ARMEncoding encoding) {
717  return EmulateMOVRdRm(opcode, encoding);
718}
719
720// Move from register to register.
721// MOV (register)
722bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
723                                           const ARMEncoding encoding) {
724#if 0
725    // ARM pseudo code...
726    if (ConditionPassed())
727    {
728        EncodingSpecificOperations();
729        result = R[m];
730        if d == 15 then
731            ALUWritePC(result); // setflags is always FALSE here
732        else
733            R[d] = result;
734            if setflags then
735                APSR.N = result<31>;
736                APSR.Z = IsZeroBit(result);
737                // APSR.C unchanged
738                // APSR.V unchanged
739    }
740#endif
741
742  bool success = false;
743
744  if (ConditionPassed(opcode)) {
745    uint32_t Rm; // the source register
746    uint32_t Rd; // the destination register
747    bool setflags;
748    switch (encoding) {
749    case eEncodingT1:
750      Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
751      Rm = Bits32(opcode, 6, 3);
752      setflags = false;
753      if (Rd == 15 && InITBlock() && !LastInITBlock())
754        return false;
755      break;
756    case eEncodingT2:
757      Rd = Bits32(opcode, 2, 0);
758      Rm = Bits32(opcode, 5, 3);
759      setflags = true;
760      if (InITBlock())
761        return false;
762      break;
763    case eEncodingT3:
764      Rd = Bits32(opcode, 11, 8);
765      Rm = Bits32(opcode, 3, 0);
766      setflags = BitIsSet(opcode, 20);
767      // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
768      if (setflags && (BadReg(Rd) || BadReg(Rm)))
769        return false;
770      // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
771      // UNPREDICTABLE;
772      if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
773        return false;
774      break;
775    case eEncodingA1:
776      Rd = Bits32(opcode, 15, 12);
777      Rm = Bits32(opcode, 3, 0);
778      setflags = BitIsSet(opcode, 20);
779
780      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
781      // instructions;
782      if (Rd == 15 && setflags)
783        return EmulateSUBSPcLrEtc(opcode, encoding);
784      break;
785    default:
786      return false;
787    }
788    uint32_t result = ReadCoreReg(Rm, &success);
789    if (!success)
790      return false;
791
792    // The context specifies that Rm is to be moved into Rd.
793    EmulateInstruction::Context context;
794    if (Rd == 13)
795      context.type = EmulateInstruction::eContextAdjustStackPointer;
796    else
797      context.type = EmulateInstruction::eContextRegisterPlusOffset;
798    RegisterInfo dwarf_reg;
799    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
800    context.SetRegisterPlusOffset(dwarf_reg, 0);
801
802    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
803      return false;
804  }
805  return true;
806}
807
808// Move (immediate) writes an immediate value to the destination register.  It
809// can optionally update the condition flags based on the value.
810// MOV (immediate)
811bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
812                                            const ARMEncoding encoding) {
813#if 0
814    // ARM pseudo code...
815    if (ConditionPassed())
816    {
817        EncodingSpecificOperations();
818        result = imm32;
819        if d == 15 then         // Can only occur for ARM encoding
820            ALUWritePC(result); // setflags is always FALSE here
821        else
822            R[d] = result;
823            if setflags then
824                APSR.N = result<31>;
825                APSR.Z = IsZeroBit(result);
826                APSR.C = carry;
827                // APSR.V unchanged
828    }
829#endif
830
831  if (ConditionPassed(opcode)) {
832    uint32_t Rd;    // the destination register
833    uint32_t imm32; // the immediate value to be written to Rd
834    uint32_t carry =
835        0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
836           // for setflags == false, this value is a don't care
837           // initialized to 0 to silence the static analyzer
838    bool setflags;
839    switch (encoding) {
840    case eEncodingT1:
841      Rd = Bits32(opcode, 10, 8);
842      setflags = !InITBlock();
843      imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
844      carry = APSR_C;
845
846      break;
847
848    case eEncodingT2:
849      Rd = Bits32(opcode, 11, 8);
850      setflags = BitIsSet(opcode, 20);
851      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
852      if (BadReg(Rd))
853        return false;
854
855      break;
856
857    case eEncodingT3: {
858      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
859      // 32);
860      Rd = Bits32(opcode, 11, 8);
861      setflags = false;
862      uint32_t imm4 = Bits32(opcode, 19, 16);
863      uint32_t imm3 = Bits32(opcode, 14, 12);
864      uint32_t i = Bit32(opcode, 26);
865      uint32_t imm8 = Bits32(opcode, 7, 0);
866      imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
867
868      // if BadReg(d) then UNPREDICTABLE;
869      if (BadReg(Rd))
870        return false;
871    } break;
872
873    case eEncodingA1:
874      // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
875      // ARMExpandImm_C(imm12, APSR.C);
876      Rd = Bits32(opcode, 15, 12);
877      setflags = BitIsSet(opcode, 20);
878      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
879
880      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
881      // instructions;
882      if ((Rd == 15) && setflags)
883        return EmulateSUBSPcLrEtc(opcode, encoding);
884
885      break;
886
887    case eEncodingA2: {
888      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
889      Rd = Bits32(opcode, 15, 12);
890      setflags = false;
891      uint32_t imm4 = Bits32(opcode, 19, 16);
892      uint32_t imm12 = Bits32(opcode, 11, 0);
893      imm32 = (imm4 << 12) | imm12;
894
895      // if d == 15 then UNPREDICTABLE;
896      if (Rd == 15)
897        return false;
898    } break;
899
900    default:
901      return false;
902    }
903    uint32_t result = imm32;
904
905    // The context specifies that an immediate is to be moved into Rd.
906    EmulateInstruction::Context context;
907    context.type = EmulateInstruction::eContextImmediate;
908    context.SetNoArgs();
909
910    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
911      return false;
912  }
913  return true;
914}
915
916// MUL multiplies two register values.  The least significant 32 bits of the
917// result are written to the destination
918// register.  These 32 bits do not depend on whether the source register values
919// are considered to be signed values or
920// unsigned values.
921//
922// Optionally, it can update the condition flags based on the result.  In the
923// Thumb instruction set, this option is
924// limited to only a few forms of the instruction.
925bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
926                                       const ARMEncoding encoding) {
927#if 0
928    if ConditionPassed() then
929        EncodingSpecificOperations();
930        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
931        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
932        result = operand1 * operand2;
933        R[d] = result<31:0>;
934        if setflags then
935            APSR.N = result<31>;
936            APSR.Z = IsZeroBit(result);
937            if ArchVersion() == 4 then
938                APSR.C = bit UNKNOWN;
939            // else APSR.C unchanged
940            // APSR.V always unchanged
941#endif
942
943  if (ConditionPassed(opcode)) {
944    uint32_t d;
945    uint32_t n;
946    uint32_t m;
947    bool setflags;
948
949    // EncodingSpecificOperations();
950    switch (encoding) {
951    case eEncodingT1:
952      // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
953      d = Bits32(opcode, 2, 0);
954      n = Bits32(opcode, 5, 3);
955      m = Bits32(opcode, 2, 0);
956      setflags = !InITBlock();
957
958      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
959      if ((ArchVersion() < ARMv6) && (d == n))
960        return false;
961
962      break;
963
964    case eEncodingT2:
965      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
966      d = Bits32(opcode, 11, 8);
967      n = Bits32(opcode, 19, 16);
968      m = Bits32(opcode, 3, 0);
969      setflags = false;
970
971      // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
972      if (BadReg(d) || BadReg(n) || BadReg(m))
973        return false;
974
975      break;
976
977    case eEncodingA1:
978      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
979      d = Bits32(opcode, 19, 16);
980      n = Bits32(opcode, 3, 0);
981      m = Bits32(opcode, 11, 8);
982      setflags = BitIsSet(opcode, 20);
983
984      // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
985      if ((d == 15) || (n == 15) || (m == 15))
986        return false;
987
988      // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
989      if ((ArchVersion() < ARMv6) && (d == n))
990        return false;
991
992      break;
993
994    default:
995      return false;
996    }
997
998    bool success = false;
999
1000    // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
1001    // results
1002    uint64_t operand1 =
1003        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1004    if (!success)
1005      return false;
1006
1007    // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
1008    // results
1009    uint64_t operand2 =
1010        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1011    if (!success)
1012      return false;
1013
1014    // result = operand1 * operand2;
1015    uint64_t result = operand1 * operand2;
1016
1017    // R[d] = result<31:0>;
1018    RegisterInfo op1_reg;
1019    RegisterInfo op2_reg;
1020    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1021    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1022
1023    EmulateInstruction::Context context;
1024    context.type = eContextArithmetic;
1025    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
1026
1027    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
1028                               (0x0000ffff & result)))
1029      return false;
1030
1031    // if setflags then
1032    if (setflags) {
1033      // APSR.N = result<31>;
1034      // APSR.Z = IsZeroBit(result);
1035      m_new_inst_cpsr = m_opcode_cpsr;
1036      SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
1037      SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1038      if (m_new_inst_cpsr != m_opcode_cpsr) {
1039        if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1040                                   LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1041          return false;
1042      }
1043
1044      // if ArchVersion() == 4 then
1045      // APSR.C = bit UNKNOWN;
1046    }
1047  }
1048  return true;
1049}
1050
1051// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
1052// the destination register.
1053// It can optionally update the condition flags based on the value.
1054bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
1055                                          const ARMEncoding encoding) {
1056#if 0
1057    // ARM pseudo code...
1058    if (ConditionPassed())
1059    {
1060        EncodingSpecificOperations();
1061        result = NOT(imm32);
1062        if d == 15 then         // Can only occur for ARM encoding
1063            ALUWritePC(result); // setflags is always FALSE here
1064        else
1065            R[d] = result;
1066            if setflags then
1067                APSR.N = result<31>;
1068                APSR.Z = IsZeroBit(result);
1069                APSR.C = carry;
1070                // APSR.V unchanged
1071    }
1072#endif
1073
1074  if (ConditionPassed(opcode)) {
1075    uint32_t Rd;    // the destination register
1076    uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1077    uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1078    bool setflags;
1079    switch (encoding) {
1080    case eEncodingT1:
1081      Rd = Bits32(opcode, 11, 8);
1082      setflags = BitIsSet(opcode, 20);
1083      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1084      break;
1085    case eEncodingA1:
1086      Rd = Bits32(opcode, 15, 12);
1087      setflags = BitIsSet(opcode, 20);
1088      imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1089
1090      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1091      // instructions;
1092      if (Rd == 15 && setflags)
1093        return EmulateSUBSPcLrEtc(opcode, encoding);
1094      break;
1095    default:
1096      return false;
1097    }
1098    uint32_t result = ~imm32;
1099
1100    // The context specifies that an immediate is to be moved into Rd.
1101    EmulateInstruction::Context context;
1102    context.type = EmulateInstruction::eContextImmediate;
1103    context.SetNoArgs();
1104
1105    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1106      return false;
1107  }
1108  return true;
1109}
1110
1111// Bitwise NOT (register) writes the bitwise inverse of a register value to the
1112// destination register.
1113// It can optionally update the condition flags based on the result.
1114bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
1115                                          const ARMEncoding encoding) {
1116#if 0
1117    // ARM pseudo code...
1118    if (ConditionPassed())
1119    {
1120        EncodingSpecificOperations();
1121        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1122        result = NOT(shifted);
1123        if d == 15 then         // Can only occur for ARM encoding
1124            ALUWritePC(result); // setflags is always FALSE here
1125        else
1126            R[d] = result;
1127            if setflags then
1128                APSR.N = result<31>;
1129                APSR.Z = IsZeroBit(result);
1130                APSR.C = carry;
1131                // APSR.V unchanged
1132    }
1133#endif
1134
1135  if (ConditionPassed(opcode)) {
1136    uint32_t Rm; // the source register
1137    uint32_t Rd; // the destination register
1138    ARM_ShifterType shift_t;
1139    uint32_t shift_n; // the shift applied to the value read from Rm
1140    bool setflags;
1141    uint32_t carry; // the carry bit after the shift operation
1142    switch (encoding) {
1143    case eEncodingT1:
1144      Rd = Bits32(opcode, 2, 0);
1145      Rm = Bits32(opcode, 5, 3);
1146      setflags = !InITBlock();
1147      shift_t = SRType_LSL;
1148      shift_n = 0;
1149      if (InITBlock())
1150        return false;
1151      break;
1152    case eEncodingT2:
1153      Rd = Bits32(opcode, 11, 8);
1154      Rm = Bits32(opcode, 3, 0);
1155      setflags = BitIsSet(opcode, 20);
1156      shift_n = DecodeImmShiftThumb(opcode, shift_t);
1157      // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1158      if (BadReg(Rd) || BadReg(Rm))
1159        return false;
1160      break;
1161    case eEncodingA1:
1162      Rd = Bits32(opcode, 15, 12);
1163      Rm = Bits32(opcode, 3, 0);
1164      setflags = BitIsSet(opcode, 20);
1165      shift_n = DecodeImmShiftARM(opcode, shift_t);
1166      break;
1167    default:
1168      return false;
1169    }
1170    bool success = false;
1171    uint32_t value = ReadCoreReg(Rm, &success);
1172    if (!success)
1173      return false;
1174
1175    uint32_t shifted =
1176        Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1177    if (!success)
1178      return false;
1179    uint32_t result = ~shifted;
1180
1181    // The context specifies that an immediate is to be moved into Rd.
1182    EmulateInstruction::Context context;
1183    context.type = EmulateInstruction::eContextImmediate;
1184    context.SetNoArgs();
1185
1186    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1187      return false;
1188  }
1189  return true;
1190}
1191
1192// PC relative immediate load into register, possibly followed by ADD (SP plus
1193// register).
1194// LDR (literal)
1195bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
1196                                                   const ARMEncoding encoding) {
1197#if 0
1198    // ARM pseudo code...
1199    if (ConditionPassed())
1200    {
1201        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1202        base = Align(PC,4);
1203        address = if add then (base + imm32) else (base - imm32);
1204        data = MemU[address,4];
1205        if t == 15 then
1206            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1207        elsif UnalignedSupport() || address<1:0> = '00' then
1208            R[t] = data;
1209        else // Can only apply before ARMv7
1210            if CurrentInstrSet() == InstrSet_ARM then
1211                R[t] = ROR(data, 8*UInt(address<1:0>));
1212            else
1213                R[t] = bits(32) UNKNOWN;
1214    }
1215#endif
1216
1217  if (ConditionPassed(opcode)) {
1218    bool success = false;
1219    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1220    if (!success)
1221      return false;
1222
1223    // PC relative immediate load context
1224    EmulateInstruction::Context context;
1225    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1226    RegisterInfo pc_reg;
1227    GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
1228    context.SetRegisterPlusOffset(pc_reg, 0);
1229
1230    uint32_t Rt;    // the destination register
1231    uint32_t imm32; // immediate offset from the PC
1232    bool add;       // +imm32 or -imm32?
1233    addr_t base;    // the base address
1234    addr_t address; // the PC relative address
1235    uint32_t data;  // the literal data value from the PC relative load
1236    switch (encoding) {
1237    case eEncodingT1:
1238      Rt = Bits32(opcode, 10, 8);
1239      imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1240      add = true;
1241      break;
1242    case eEncodingT2:
1243      Rt = Bits32(opcode, 15, 12);
1244      imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1245      add = BitIsSet(opcode, 23);
1246      if (Rt == 15 && InITBlock() && !LastInITBlock())
1247        return false;
1248      break;
1249    default:
1250      return false;
1251    }
1252
1253    base = Align(pc, 4);
1254    if (add)
1255      address = base + imm32;
1256    else
1257      address = base - imm32;
1258
1259    context.SetRegisterPlusOffset(pc_reg, address - base);
1260    data = MemURead(context, address, 4, 0, &success);
1261    if (!success)
1262      return false;
1263
1264    if (Rt == 15) {
1265      if (Bits32(address, 1, 0) == 0) {
1266        // In ARMv5T and above, this is an interworking branch.
1267        if (!LoadWritePC(context, data))
1268          return false;
1269      } else
1270        return false;
1271    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
1272      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
1273                                 data))
1274        return false;
1275    } else // We don't handle ARM for now.
1276      return false;
1277  }
1278  return true;
1279}
1280
1281// An add operation to adjust the SP.
1282// ADD (SP plus immediate)
1283bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
1284                                            const ARMEncoding encoding) {
1285#if 0
1286    // ARM pseudo code...
1287    if (ConditionPassed())
1288    {
1289        EncodingSpecificOperations();
1290        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1291        if d == 15 then // Can only occur for ARM encoding
1292            ALUWritePC(result); // setflags is always FALSE here
1293        else
1294            R[d] = result;
1295            if setflags then
1296                APSR.N = result<31>;
1297                APSR.Z = IsZeroBit(result);
1298                APSR.C = carry;
1299                APSR.V = overflow;
1300    }
1301#endif
1302
1303  bool success = false;
1304
1305  if (ConditionPassed(opcode)) {
1306    const addr_t sp = ReadCoreReg(SP_REG, &success);
1307    if (!success)
1308      return false;
1309    uint32_t imm32; // the immediate operand
1310    uint32_t d;
1311    bool setflags;
1312    switch (encoding) {
1313    case eEncodingT1:
1314      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1315      d = Bits32(opcode, 10, 8);
1316      imm32 = (Bits32(opcode, 7, 0) << 2);
1317      setflags = false;
1318      break;
1319
1320    case eEncodingT2:
1321      // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1322      d = 13;
1323      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1324      setflags = false;
1325      break;
1326
1327    case eEncodingT3:
1328      // d = UInt(Rd); setflags = (S == "1"); imm32 =
1329      // ThumbExpandImm(i:imm3:imm8);
1330      d = Bits32(opcode, 11, 8);
1331      imm32 = ThumbExpandImm(opcode);
1332      setflags = Bit32(opcode, 20);
1333
1334      // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1335      if (d == 15 && setflags == 1)
1336        return false; // CMN (immediate) not yet supported
1337
1338      // if d == 15 && S == "0" then UNPREDICTABLE;
1339      if (d == 15 && setflags == 0)
1340        return false;
1341      break;
1342
1343    case eEncodingT4: {
1344      // if Rn == '1111' then SEE ADR;
1345      // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1346      d = Bits32(opcode, 11, 8);
1347      setflags = false;
1348      uint32_t i = Bit32(opcode, 26);
1349      uint32_t imm3 = Bits32(opcode, 14, 12);
1350      uint32_t imm8 = Bits32(opcode, 7, 0);
1351      imm32 = (i << 11) | (imm3 << 8) | imm8;
1352
1353      // if d == 15 then UNPREDICTABLE;
1354      if (d == 15)
1355        return false;
1356    } break;
1357
1358    default:
1359      return false;
1360    }
1361    // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1362    AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
1363
1364    EmulateInstruction::Context context;
1365    if (d == 13)
1366      context.type = EmulateInstruction::eContextAdjustStackPointer;
1367    else
1368      context.type = EmulateInstruction::eContextRegisterPlusOffset;
1369
1370    RegisterInfo sp_reg;
1371    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1372    context.SetRegisterPlusOffset(sp_reg, res.result - sp);
1373
1374    if (d == 15) {
1375      if (!ALUWritePC(context, res.result))
1376        return false;
1377    } else {
1378      // R[d] = result;
1379      // if setflags then
1380      //     APSR.N = result<31>;
1381      //     APSR.Z = IsZeroBit(result);
1382      //     APSR.C = carry;
1383      //     APSR.V = overflow;
1384      if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
1385                                     res.carry_out, res.overflow))
1386        return false;
1387    }
1388  }
1389  return true;
1390}
1391
1392// An add operation to adjust the SP.
1393// ADD (SP plus register)
1394bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
1395                                           const ARMEncoding encoding) {
1396#if 0
1397    // ARM pseudo code...
1398    if (ConditionPassed())
1399    {
1400        EncodingSpecificOperations();
1401        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1402        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1403        if d == 15 then
1404            ALUWritePC(result); // setflags is always FALSE here
1405        else
1406            R[d] = result;
1407            if setflags then
1408                APSR.N = result<31>;
1409                APSR.Z = IsZeroBit(result);
1410                APSR.C = carry;
1411                APSR.V = overflow;
1412    }
1413#endif
1414
1415  bool success = false;
1416
1417  if (ConditionPassed(opcode)) {
1418    const addr_t sp = ReadCoreReg(SP_REG, &success);
1419    if (!success)
1420      return false;
1421    uint32_t Rm; // the second operand
1422    switch (encoding) {
1423    case eEncodingT2:
1424      Rm = Bits32(opcode, 6, 3);
1425      break;
1426    default:
1427      return false;
1428    }
1429    int32_t reg_value = ReadCoreReg(Rm, &success);
1430    if (!success)
1431      return false;
1432
1433    addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1434
1435    EmulateInstruction::Context context;
1436    context.type = eContextArithmetic;
1437    RegisterInfo sp_reg;
1438    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1439
1440    RegisterInfo other_reg;
1441    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1442    context.SetRegisterRegisterOperands(sp_reg, other_reg);
1443
1444    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1445                               LLDB_REGNUM_GENERIC_SP, addr))
1446      return false;
1447  }
1448  return true;
1449}
1450
1451// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1452// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1453// from Thumb to ARM.
1454// BLX (immediate)
1455bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
1456                                                const ARMEncoding encoding) {
1457#if 0
1458    // ARM pseudo code...
1459    if (ConditionPassed())
1460    {
1461        EncodingSpecificOperations();
1462        if CurrentInstrSet() == InstrSet_ARM then
1463            LR = PC - 4;
1464        else
1465            LR = PC<31:1> : '1';
1466        if targetInstrSet == InstrSet_ARM then
1467            targetAddress = Align(PC,4) + imm32;
1468        else
1469            targetAddress = PC + imm32;
1470        SelectInstrSet(targetInstrSet);
1471        BranchWritePC(targetAddress);
1472    }
1473#endif
1474
1475  bool success = true;
1476
1477  if (ConditionPassed(opcode)) {
1478    EmulateInstruction::Context context;
1479    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1480    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1481    if (!success)
1482      return false;
1483    addr_t lr;     // next instruction address
1484    addr_t target; // target address
1485    int32_t imm32; // PC-relative offset
1486    switch (encoding) {
1487    case eEncodingT1: {
1488      lr = pc | 1u; // return address
1489      uint32_t S = Bit32(opcode, 26);
1490      uint32_t imm10 = Bits32(opcode, 25, 16);
1491      uint32_t J1 = Bit32(opcode, 13);
1492      uint32_t J2 = Bit32(opcode, 11);
1493      uint32_t imm11 = Bits32(opcode, 10, 0);
1494      uint32_t I1 = !(J1 ^ S);
1495      uint32_t I2 = !(J2 ^ S);
1496      uint32_t imm25 =
1497          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1498      imm32 = llvm::SignExtend32<25>(imm25);
1499      target = pc + imm32;
1500      SelectInstrSet(eModeThumb);
1501      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
1502      if (InITBlock() && !LastInITBlock())
1503        return false;
1504      break;
1505    }
1506    case eEncodingT2: {
1507      lr = pc | 1u; // return address
1508      uint32_t S = Bit32(opcode, 26);
1509      uint32_t imm10H = Bits32(opcode, 25, 16);
1510      uint32_t J1 = Bit32(opcode, 13);
1511      uint32_t J2 = Bit32(opcode, 11);
1512      uint32_t imm10L = Bits32(opcode, 10, 1);
1513      uint32_t I1 = !(J1 ^ S);
1514      uint32_t I2 = !(J2 ^ S);
1515      uint32_t imm25 =
1516          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1517      imm32 = llvm::SignExtend32<25>(imm25);
1518      target = Align(pc, 4) + imm32;
1519      SelectInstrSet(eModeARM);
1520      context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
1521      if (InITBlock() && !LastInITBlock())
1522        return false;
1523      break;
1524    }
1525    case eEncodingA1:
1526      lr = pc - 4; // return address
1527      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1528      target = Align(pc, 4) + imm32;
1529      SelectInstrSet(eModeARM);
1530      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
1531      break;
1532    case eEncodingA2:
1533      lr = pc - 4; // return address
1534      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
1535                                     Bits32(opcode, 24, 24) << 1);
1536      target = pc + imm32;
1537      SelectInstrSet(eModeThumb);
1538      context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
1539      break;
1540    default:
1541      return false;
1542    }
1543    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1544                               LLDB_REGNUM_GENERIC_RA, lr))
1545      return false;
1546    if (!BranchWritePC(context, target))
1547      return false;
1548    if (m_opcode_cpsr != m_new_inst_cpsr)
1549      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1550                                 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1551        return false;
1552  }
1553  return true;
1554}
1555
1556// Branch with Link and Exchange (register) calls a subroutine at an address and
1557// instruction set specified by a register.
1558// BLX (register)
1559bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
1560                                         const ARMEncoding encoding) {
1561#if 0
1562    // ARM pseudo code...
1563    if (ConditionPassed())
1564    {
1565        EncodingSpecificOperations();
1566        target = R[m];
1567        if CurrentInstrSet() == InstrSet_ARM then
1568            next_instr_addr = PC - 4;
1569            LR = next_instr_addr;
1570        else
1571            next_instr_addr = PC - 2;
1572            LR = next_instr_addr<31:1> : '1';
1573        BXWritePC(target);
1574    }
1575#endif
1576
1577  bool success = false;
1578
1579  if (ConditionPassed(opcode)) {
1580    EmulateInstruction::Context context;
1581    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1582    const uint32_t pc = ReadCoreReg(PC_REG, &success);
1583    addr_t lr; // next instruction address
1584    if (!success)
1585      return false;
1586    uint32_t Rm; // the register with the target address
1587    switch (encoding) {
1588    case eEncodingT1:
1589      lr = (pc - 2) | 1u; // return address
1590      Rm = Bits32(opcode, 6, 3);
1591      // if m == 15 then UNPREDICTABLE;
1592      if (Rm == 15)
1593        return false;
1594      if (InITBlock() && !LastInITBlock())
1595        return false;
1596      break;
1597    case eEncodingA1:
1598      lr = pc - 4; // return address
1599      Rm = Bits32(opcode, 3, 0);
1600      // if m == 15 then UNPREDICTABLE;
1601      if (Rm == 15)
1602        return false;
1603      break;
1604    default:
1605      return false;
1606    }
1607    addr_t target = ReadCoreReg(Rm, &success);
1608    if (!success)
1609      return false;
1610    RegisterInfo dwarf_reg;
1611    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1612    context.SetRegister(dwarf_reg);
1613    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
1614                               LLDB_REGNUM_GENERIC_RA, lr))
1615      return false;
1616    if (!BXWritePC(context, target))
1617      return false;
1618  }
1619  return true;
1620}
1621
1622// Branch and Exchange causes a branch to an address and instruction set
1623// specified by a register.
1624bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
1625                                        const ARMEncoding encoding) {
1626#if 0
1627    // ARM pseudo code...
1628    if (ConditionPassed())
1629    {
1630        EncodingSpecificOperations();
1631        BXWritePC(R[m]);
1632    }
1633#endif
1634
1635  if (ConditionPassed(opcode)) {
1636    EmulateInstruction::Context context;
1637    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1638    uint32_t Rm; // the register with the target address
1639    switch (encoding) {
1640    case eEncodingT1:
1641      Rm = Bits32(opcode, 6, 3);
1642      if (InITBlock() && !LastInITBlock())
1643        return false;
1644      break;
1645    case eEncodingA1:
1646      Rm = Bits32(opcode, 3, 0);
1647      break;
1648    default:
1649      return false;
1650    }
1651    bool success = false;
1652    addr_t target = ReadCoreReg(Rm, &success);
1653    if (!success)
1654      return false;
1655
1656    RegisterInfo dwarf_reg;
1657    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1658    context.SetRegister(dwarf_reg);
1659    if (!BXWritePC(context, target))
1660      return false;
1661  }
1662  return true;
1663}
1664
1665// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
1666// attempt fails, it branches to an
1667// address and instruction set specified by a register as though it were a BX
1668// instruction.
1669//
1670// TODO: Emulate Jazelle architecture?
1671//       We currently assume that switching to Jazelle state fails, thus
1672//       treating BXJ as a BX operation.
1673bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
1674                                         const ARMEncoding encoding) {
1675#if 0
1676    // ARM pseudo code...
1677    if (ConditionPassed())
1678    {
1679        EncodingSpecificOperations();
1680        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1681            BXWritePC(R[m]);
1682        else
1683            if JazelleAcceptsExecution() then
1684                SwitchToJazelleExecution();
1685            else
1686                SUBARCHITECTURE_DEFINED handler call;
1687    }
1688#endif
1689
1690  if (ConditionPassed(opcode)) {
1691    EmulateInstruction::Context context;
1692    context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1693    uint32_t Rm; // the register with the target address
1694    switch (encoding) {
1695    case eEncodingT1:
1696      Rm = Bits32(opcode, 19, 16);
1697      if (BadReg(Rm))
1698        return false;
1699      if (InITBlock() && !LastInITBlock())
1700        return false;
1701      break;
1702    case eEncodingA1:
1703      Rm = Bits32(opcode, 3, 0);
1704      if (Rm == 15)
1705        return false;
1706      break;
1707    default:
1708      return false;
1709    }
1710    bool success = false;
1711    addr_t target = ReadCoreReg(Rm, &success);
1712    if (!success)
1713      return false;
1714
1715    RegisterInfo dwarf_reg;
1716    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1717    context.SetRegister(dwarf_reg);
1718    if (!BXWritePC(context, target))
1719      return false;
1720  }
1721  return true;
1722}
1723
1724// Set r7 to point to some ip offset.
1725// SUB (immediate)
1726bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
1727                                              const ARMEncoding encoding) {
1728#if 0
1729    // ARM pseudo code...
1730    if (ConditionPassed())
1731    {
1732        EncodingSpecificOperations();
1733        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1734        if d == 15 then // Can only occur for ARM encoding
1735           ALUWritePC(result); // setflags is always FALSE here
1736        else
1737            R[d] = result;
1738            if setflags then
1739                APSR.N = result<31>;
1740                APSR.Z = IsZeroBit(result);
1741                APSR.C = carry;
1742                APSR.V = overflow;
1743    }
1744#endif
1745
1746  if (ConditionPassed(opcode)) {
1747    bool success = false;
1748    const addr_t ip = ReadCoreReg(12, &success);
1749    if (!success)
1750      return false;
1751    uint32_t imm32;
1752    switch (encoding) {
1753    case eEncodingA1:
1754      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1755      break;
1756    default:
1757      return false;
1758    }
1759    addr_t ip_offset = imm32;
1760    addr_t addr = ip - ip_offset; // the adjusted ip value
1761
1762    EmulateInstruction::Context context;
1763    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1764    RegisterInfo dwarf_reg;
1765    GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1766    context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
1767
1768    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
1769      return false;
1770  }
1771  return true;
1772}
1773
1774// Set ip to point to some stack offset.
1775// SUB (SP minus immediate)
1776bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
1777                                              const ARMEncoding encoding) {
1778#if 0
1779    // ARM pseudo code...
1780    if (ConditionPassed())
1781    {
1782        EncodingSpecificOperations();
1783        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1784        if d == 15 then // Can only occur for ARM encoding
1785           ALUWritePC(result); // setflags is always FALSE here
1786        else
1787            R[d] = result;
1788            if setflags then
1789                APSR.N = result<31>;
1790                APSR.Z = IsZeroBit(result);
1791                APSR.C = carry;
1792                APSR.V = overflow;
1793    }
1794#endif
1795
1796  if (ConditionPassed(opcode)) {
1797    bool success = false;
1798    const addr_t sp = ReadCoreReg(SP_REG, &success);
1799    if (!success)
1800      return false;
1801    uint32_t imm32;
1802    switch (encoding) {
1803    case eEncodingA1:
1804      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1805      break;
1806    default:
1807      return false;
1808    }
1809    addr_t sp_offset = imm32;
1810    addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1811
1812    EmulateInstruction::Context context;
1813    context.type = EmulateInstruction::eContextRegisterPlusOffset;
1814    RegisterInfo dwarf_reg;
1815    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1816    context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
1817
1818    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
1819      return false;
1820  }
1821  return true;
1822}
1823
1824// This instruction subtracts an immediate value from the SP value, and writes
1825// the result to the destination register.
1826//
1827// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
1828// storage.
1829bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
1830                                            const ARMEncoding encoding) {
1831#if 0
1832    // ARM pseudo code...
1833    if (ConditionPassed())
1834    {
1835        EncodingSpecificOperations();
1836        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1837        if d == 15 then        // Can only occur for ARM encoding
1838           ALUWritePC(result); // setflags is always FALSE here
1839        else
1840            R[d] = result;
1841            if setflags then
1842                APSR.N = result<31>;
1843                APSR.Z = IsZeroBit(result);
1844                APSR.C = carry;
1845                APSR.V = overflow;
1846    }
1847#endif
1848
1849  bool success = false;
1850  if (ConditionPassed(opcode)) {
1851    const addr_t sp = ReadCoreReg(SP_REG, &success);
1852    if (!success)
1853      return false;
1854
1855    uint32_t Rd;
1856    bool setflags;
1857    uint32_t imm32;
1858    switch (encoding) {
1859    case eEncodingT1:
1860      Rd = 13;
1861      setflags = false;
1862      imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1863      break;
1864    case eEncodingT2:
1865      Rd = Bits32(opcode, 11, 8);
1866      setflags = BitIsSet(opcode, 20);
1867      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1868      if (Rd == 15 && setflags)
1869        return EmulateCMPImm(opcode, eEncodingT2);
1870      if (Rd == 15 && !setflags)
1871        return false;
1872      break;
1873    case eEncodingT3:
1874      Rd = Bits32(opcode, 11, 8);
1875      setflags = false;
1876      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1877      if (Rd == 15)
1878        return false;
1879      break;
1880    case eEncodingA1:
1881      Rd = Bits32(opcode, 15, 12);
1882      setflags = BitIsSet(opcode, 20);
1883      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1884
1885      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
1886      // instructions;
1887      if (Rd == 15 && setflags)
1888        return EmulateSUBSPcLrEtc(opcode, encoding);
1889      break;
1890    default:
1891      return false;
1892    }
1893    AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1894
1895    EmulateInstruction::Context context;
1896    if (Rd == 13) {
1897      uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
1898                              // to negate it, or the wrong
1899      // value gets passed down to context.SetImmediateSigned.
1900      context.type = EmulateInstruction::eContextAdjustStackPointer;
1901      context.SetImmediateSigned(-imm64); // the stack pointer offset
1902    } else {
1903      context.type = EmulateInstruction::eContextImmediate;
1904      context.SetNoArgs();
1905    }
1906
1907    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
1908                                   res.carry_out, res.overflow))
1909      return false;
1910  }
1911  return true;
1912}
1913
1914// A store operation to the stack that also updates the SP.
1915bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
1916                                           const ARMEncoding encoding) {
1917#if 0
1918    // ARM pseudo code...
1919    if (ConditionPassed())
1920    {
1921        EncodingSpecificOperations();
1922        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1923        address = if index then offset_addr else R[n];
1924        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1925        if wback then R[n] = offset_addr;
1926    }
1927#endif
1928
1929  bool success = false;
1930  if (ConditionPassed(opcode)) {
1931    const uint32_t addr_byte_size = GetAddressByteSize();
1932    const addr_t sp = ReadCoreReg(SP_REG, &success);
1933    if (!success)
1934      return false;
1935    uint32_t Rt; // the source register
1936    uint32_t imm12;
1937    uint32_t
1938        Rn; // This function assumes Rn is the SP, but we should verify that.
1939
1940    bool index;
1941    bool add;
1942    bool wback;
1943    switch (encoding) {
1944    case eEncodingA1:
1945      Rt = Bits32(opcode, 15, 12);
1946      imm12 = Bits32(opcode, 11, 0);
1947      Rn = Bits32(opcode, 19, 16);
1948
1949      if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1950        return false;
1951
1952      index = BitIsSet(opcode, 24);
1953      add = BitIsSet(opcode, 23);
1954      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
1955
1956      if (wback && ((Rn == 15) || (Rn == Rt)))
1957        return false;
1958      break;
1959    default:
1960      return false;
1961    }
1962    addr_t offset_addr;
1963    if (add)
1964      offset_addr = sp + imm12;
1965    else
1966      offset_addr = sp - imm12;
1967
1968    addr_t addr;
1969    if (index)
1970      addr = offset_addr;
1971    else
1972      addr = sp;
1973
1974    EmulateInstruction::Context context;
1975    context.type = EmulateInstruction::eContextPushRegisterOnStack;
1976    RegisterInfo sp_reg;
1977    RegisterInfo dwarf_reg;
1978
1979    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
1980    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1981    context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
1982    if (Rt != 15) {
1983      uint32_t reg_value = ReadCoreReg(Rt, &success);
1984      if (!success)
1985        return false;
1986      if (!MemUWrite(context, addr, reg_value, addr_byte_size))
1987        return false;
1988    } else {
1989      const uint32_t pc = ReadCoreReg(PC_REG, &success);
1990      if (!success)
1991        return false;
1992      if (!MemUWrite(context, addr, pc, addr_byte_size))
1993        return false;
1994    }
1995
1996    if (wback) {
1997      context.type = EmulateInstruction::eContextAdjustStackPointer;
1998      context.SetImmediateSigned(addr - sp);
1999      if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2000                                 LLDB_REGNUM_GENERIC_SP, offset_addr))
2001        return false;
2002    }
2003  }
2004  return true;
2005}
2006
2007// Vector Push stores multiple extension registers to the stack.
2008// It also updates SP to point to the start of the stored data.
2009bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
2010                                         const ARMEncoding encoding) {
2011#if 0
2012    // ARM pseudo code...
2013    if (ConditionPassed())
2014    {
2015        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2016        address = SP - imm32;
2017        SP = SP - imm32;
2018        if single_regs then
2019            for r = 0 to regs-1
2020                MemA[address,4] = S[d+r]; address = address+4;
2021        else
2022            for r = 0 to regs-1
2023                // Store as two word-aligned words in the correct order for current endianness.
2024                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2025                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2026                address = address+8;
2027    }
2028#endif
2029
2030  bool success = false;
2031  if (ConditionPassed(opcode)) {
2032    const uint32_t addr_byte_size = GetAddressByteSize();
2033    const addr_t sp = ReadCoreReg(SP_REG, &success);
2034    if (!success)
2035      return false;
2036    bool single_regs;
2037    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2038    uint32_t imm32; // stack offset
2039    uint32_t regs;  // number of registers
2040    switch (encoding) {
2041    case eEncodingT1:
2042    case eEncodingA1:
2043      single_regs = false;
2044      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2045      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2046      // If UInt(imm8) is odd, see "FSTMX".
2047      regs = Bits32(opcode, 7, 0) / 2;
2048      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2049      if (regs == 0 || regs > 16 || (d + regs) > 32)
2050        return false;
2051      break;
2052    case eEncodingT2:
2053    case eEncodingA2:
2054      single_regs = true;
2055      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2056      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2057      regs = Bits32(opcode, 7, 0);
2058      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2059      if (regs == 0 || regs > 16 || (d + regs) > 32)
2060        return false;
2061      break;
2062    default:
2063      return false;
2064    }
2065    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2066    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2067    addr_t sp_offset = imm32;
2068    addr_t addr = sp - sp_offset;
2069    uint32_t i;
2070
2071    EmulateInstruction::Context context;
2072    context.type = EmulateInstruction::eContextPushRegisterOnStack;
2073
2074    RegisterInfo dwarf_reg;
2075    RegisterInfo sp_reg;
2076    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2077    for (i = 0; i < regs; ++i) {
2078      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2079      context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
2080      // uint64_t to accommodate 64-bit registers.
2081      uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
2082      if (!success)
2083        return false;
2084      if (!MemAWrite(context, addr, reg_value, reg_byte_size))
2085        return false;
2086      addr += reg_byte_size;
2087    }
2088
2089    context.type = EmulateInstruction::eContextAdjustStackPointer;
2090    context.SetImmediateSigned(-sp_offset);
2091
2092    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2093                               LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2094      return false;
2095  }
2096  return true;
2097}
2098
2099// Vector Pop loads multiple extension registers from the stack.
2100// It also updates SP to point just above the loaded data.
2101bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
2102                                        const ARMEncoding encoding) {
2103#if 0
2104    // ARM pseudo code...
2105    if (ConditionPassed())
2106    {
2107        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2108        address = SP;
2109        SP = SP + imm32;
2110        if single_regs then
2111            for r = 0 to regs-1
2112                S[d+r] = MemA[address,4]; address = address+4;
2113        else
2114            for r = 0 to regs-1
2115                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2116                // Combine the word-aligned words in the correct order for current endianness.
2117                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2118    }
2119#endif
2120
2121  bool success = false;
2122  if (ConditionPassed(opcode)) {
2123    const uint32_t addr_byte_size = GetAddressByteSize();
2124    const addr_t sp = ReadCoreReg(SP_REG, &success);
2125    if (!success)
2126      return false;
2127    bool single_regs;
2128    uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2129    uint32_t imm32; // stack offset
2130    uint32_t regs;  // number of registers
2131    switch (encoding) {
2132    case eEncodingT1:
2133    case eEncodingA1:
2134      single_regs = false;
2135      d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2136      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2137      // If UInt(imm8) is odd, see "FLDMX".
2138      regs = Bits32(opcode, 7, 0) / 2;
2139      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2140      if (regs == 0 || regs > 16 || (d + regs) > 32)
2141        return false;
2142      break;
2143    case eEncodingT2:
2144    case eEncodingA2:
2145      single_regs = true;
2146      d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2147      imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2148      regs = Bits32(opcode, 7, 0);
2149      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2150      if (regs == 0 || regs > 16 || (d + regs) > 32)
2151        return false;
2152      break;
2153    default:
2154      return false;
2155    }
2156    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2157    uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2158    addr_t sp_offset = imm32;
2159    addr_t addr = sp;
2160    uint32_t i;
2161    uint64_t data; // uint64_t to accommodate 64-bit registers.
2162
2163    EmulateInstruction::Context context;
2164    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2165
2166    RegisterInfo dwarf_reg;
2167    RegisterInfo sp_reg;
2168    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
2169    for (i = 0; i < regs; ++i) {
2170      GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2171      context.SetAddress(addr);
2172      data = MemARead(context, addr, reg_byte_size, 0, &success);
2173      if (!success)
2174        return false;
2175      if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2176        return false;
2177      addr += reg_byte_size;
2178    }
2179
2180    context.type = EmulateInstruction::eContextAdjustStackPointer;
2181    context.SetImmediateSigned(sp_offset);
2182
2183    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2184                               LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2185      return false;
2186  }
2187  return true;
2188}
2189
2190// SVC (previously SWI)
2191bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
2192                                       const ARMEncoding encoding) {
2193#if 0
2194    // ARM pseudo code...
2195    if (ConditionPassed())
2196    {
2197        EncodingSpecificOperations();
2198        CallSupervisor();
2199    }
2200#endif
2201
2202  bool success = false;
2203
2204  if (ConditionPassed(opcode)) {
2205    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2206    addr_t lr; // next instruction address
2207    if (!success)
2208      return false;
2209    uint32_t imm32; // the immediate constant
2210    uint32_t mode;  // ARM or Thumb mode
2211    switch (encoding) {
2212    case eEncodingT1:
2213      lr = (pc + 2) | 1u; // return address
2214      imm32 = Bits32(opcode, 7, 0);
2215      mode = eModeThumb;
2216      break;
2217    case eEncodingA1:
2218      lr = pc + 4; // return address
2219      imm32 = Bits32(opcode, 23, 0);
2220      mode = eModeARM;
2221      break;
2222    default:
2223      return false;
2224    }
2225
2226    EmulateInstruction::Context context;
2227    context.type = EmulateInstruction::eContextSupervisorCall;
2228    context.SetISAAndImmediate(mode, imm32);
2229    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
2230                               LLDB_REGNUM_GENERIC_RA, lr))
2231      return false;
2232  }
2233  return true;
2234}
2235
2236// If Then makes up to four following instructions (the IT block) conditional.
2237bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
2238                                      const ARMEncoding encoding) {
2239#if 0
2240    // ARM pseudo code...
2241    EncodingSpecificOperations();
2242    ITSTATE.IT<7:0> = firstcond:mask;
2243#endif
2244
2245  m_it_session.InitIT(Bits32(opcode, 7, 0));
2246  return true;
2247}
2248
2249bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
2250                                       const ARMEncoding encoding) {
2251  // NOP, nothing to do...
2252  return true;
2253}
2254
2255// Branch causes a branch to a target address.
2256bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
2257                                     const ARMEncoding encoding) {
2258#if 0
2259    // ARM pseudo code...
2260    if (ConditionPassed())
2261    {
2262        EncodingSpecificOperations();
2263        BranchWritePC(PC + imm32);
2264    }
2265#endif
2266
2267  bool success = false;
2268
2269  if (ConditionPassed(opcode)) {
2270    EmulateInstruction::Context context;
2271    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2272    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2273    if (!success)
2274      return false;
2275    addr_t target; // target address
2276    int32_t imm32; // PC-relative offset
2277    switch (encoding) {
2278    case eEncodingT1:
2279      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2280      imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2281      target = pc + imm32;
2282      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2283      break;
2284    case eEncodingT2:
2285      imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2286      target = pc + imm32;
2287      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2288      break;
2289    case eEncodingT3:
2290      // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2291      {
2292        if (Bits32(opcode, 25, 23) == 7)
2293          return false; // See Branches and miscellaneous control on page
2294                        // A6-235.
2295
2296        uint32_t S = Bit32(opcode, 26);
2297        uint32_t imm6 = Bits32(opcode, 21, 16);
2298        uint32_t J1 = Bit32(opcode, 13);
2299        uint32_t J2 = Bit32(opcode, 11);
2300        uint32_t imm11 = Bits32(opcode, 10, 0);
2301        uint32_t imm21 =
2302            (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2303        imm32 = llvm::SignExtend32<21>(imm21);
2304        target = pc + imm32;
2305        context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2306        break;
2307      }
2308    case eEncodingT4: {
2309      uint32_t S = Bit32(opcode, 26);
2310      uint32_t imm10 = Bits32(opcode, 25, 16);
2311      uint32_t J1 = Bit32(opcode, 13);
2312      uint32_t J2 = Bit32(opcode, 11);
2313      uint32_t imm11 = Bits32(opcode, 10, 0);
2314      uint32_t I1 = !(J1 ^ S);
2315      uint32_t I2 = !(J2 ^ S);
2316      uint32_t imm25 =
2317          (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2318      imm32 = llvm::SignExtend32<25>(imm25);
2319      target = pc + imm32;
2320      context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2321      break;
2322    }
2323    case eEncodingA1:
2324      imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2325      target = pc + imm32;
2326      context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
2327      break;
2328    default:
2329      return false;
2330    }
2331    if (!BranchWritePC(context, target))
2332      return false;
2333  }
2334  return true;
2335}
2336
2337// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
2338// value in a register with
2339// zero and conditionally branch forward a constant value.  They do not affect
2340// the condition flags.
2341// CBNZ, CBZ
2342bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
2343                                      const ARMEncoding encoding) {
2344#if 0
2345    // ARM pseudo code...
2346    EncodingSpecificOperations();
2347    if nonzero ^ IsZero(R[n]) then
2348        BranchWritePC(PC + imm32);
2349#endif
2350
2351  bool success = false;
2352
2353  // Read the register value from the operand register Rn.
2354  uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2355  if (!success)
2356    return false;
2357
2358  EmulateInstruction::Context context;
2359  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2360  const uint32_t pc = ReadCoreReg(PC_REG, &success);
2361  if (!success)
2362    return false;
2363
2364  addr_t target;  // target address
2365  uint32_t imm32; // PC-relative offset to branch forward
2366  bool nonzero;
2367  switch (encoding) {
2368  case eEncodingT1:
2369    imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2370    nonzero = BitIsSet(opcode, 11);
2371    target = pc + imm32;
2372    context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
2373    break;
2374  default:
2375    return false;
2376  }
2377  if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2378    if (!BranchWritePC(context, target))
2379      return false;
2380
2381  return true;
2382}
2383
2384// Table Branch Byte causes a PC-relative forward branch using a table of single
2385// byte offsets.
2386// A base register provides a pointer to the table, and a second register
2387// supplies an index into the table.
2388// The branch length is twice the value of the byte returned from the table.
2389//
2390// Table Branch Halfword causes a PC-relative forward branch using a table of
2391// single halfword offsets.
2392// A base register provides a pointer to the table, and a second register
2393// supplies an index into the table.
2394// The branch length is twice the value of the halfword returned from the table.
2395// TBB, TBH
2396bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
2397                                      const ARMEncoding encoding) {
2398#if 0
2399    // ARM pseudo code...
2400    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2401    if is_tbh then
2402        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2403    else
2404        halfwords = UInt(MemU[R[n]+R[m], 1]);
2405    BranchWritePC(PC + 2*halfwords);
2406#endif
2407
2408  bool success = false;
2409
2410  if (ConditionPassed(opcode)) {
2411    uint32_t Rn; // the base register which contains the address of the table of
2412                 // branch lengths
2413    uint32_t Rm; // the index register which contains an integer pointing to a
2414                 // byte/halfword in the table
2415    bool is_tbh; // true if table branch halfword
2416    switch (encoding) {
2417    case eEncodingT1:
2418      Rn = Bits32(opcode, 19, 16);
2419      Rm = Bits32(opcode, 3, 0);
2420      is_tbh = BitIsSet(opcode, 4);
2421      if (Rn == 13 || BadReg(Rm))
2422        return false;
2423      if (InITBlock() && !LastInITBlock())
2424        return false;
2425      break;
2426    default:
2427      return false;
2428    }
2429
2430    // Read the address of the table from the operand register Rn.
2431    // The PC can be used, in which case the table immediately follows this
2432    // instruction.
2433    uint32_t base = ReadCoreReg(Rn, &success);
2434    if (!success)
2435      return false;
2436
2437    // the table index
2438    uint32_t index = ReadCoreReg(Rm, &success);
2439    if (!success)
2440      return false;
2441
2442    // the offsetted table address
2443    addr_t addr = base + (is_tbh ? index * 2 : index);
2444
2445    // PC-relative offset to branch forward
2446    EmulateInstruction::Context context;
2447    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2448    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2449    if (!success)
2450      return false;
2451
2452    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2453    if (!success)
2454      return false;
2455
2456    // target address
2457    addr_t target = pc + offset;
2458    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2459    context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
2460
2461    if (!BranchWritePC(context, target))
2462      return false;
2463  }
2464
2465  return true;
2466}
2467
2468// This instruction adds an immediate value to a register value, and writes the
2469// result to the destination register.
2470// It can optionally update the condition flags based on the result.
2471bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
2472                                               const ARMEncoding encoding) {
2473#if 0
2474    if ConditionPassed() then
2475        EncodingSpecificOperations();
2476        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2477        R[d] = result;
2478        if setflags then
2479            APSR.N = result<31>;
2480            APSR.Z = IsZeroBit(result);
2481            APSR.C = carry;
2482            APSR.V = overflow;
2483#endif
2484
2485  bool success = false;
2486
2487  if (ConditionPassed(opcode)) {
2488    uint32_t d;
2489    uint32_t n;
2490    bool setflags;
2491    uint32_t imm32;
2492    uint32_t carry_out;
2493
2494    // EncodingSpecificOperations();
2495    switch (encoding) {
2496    case eEncodingT1:
2497      // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
2498      // ZeroExtend(imm3, 32);
2499      d = Bits32(opcode, 2, 0);
2500      n = Bits32(opcode, 5, 3);
2501      setflags = !InITBlock();
2502      imm32 = Bits32(opcode, 8, 6);
2503
2504      break;
2505
2506    case eEncodingT2:
2507      // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
2508      // ZeroExtend(imm8, 32);
2509      d = Bits32(opcode, 10, 8);
2510      n = Bits32(opcode, 10, 8);
2511      setflags = !InITBlock();
2512      imm32 = Bits32(opcode, 7, 0);
2513
2514      break;
2515
2516    case eEncodingT3:
2517      // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2518      // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
2519      // ThumbExpandImm(i:imm3:imm8);
2520      d = Bits32(opcode, 11, 8);
2521      n = Bits32(opcode, 19, 16);
2522      setflags = BitIsSet(opcode, 20);
2523      imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
2524
2525      // if Rn == '1101' then SEE ADD (SP plus immediate);
2526      if (n == 13)
2527        return EmulateADDSPImm(opcode, eEncodingT3);
2528
2529      // if BadReg(d) || n == 15 then UNPREDICTABLE;
2530      if (BadReg(d) || (n == 15))
2531        return false;
2532
2533      break;
2534
2535    case eEncodingT4: {
2536      // if Rn == '1111' then SEE ADR;
2537      // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
2538      // ZeroExtend(i:imm3:imm8, 32);
2539      d = Bits32(opcode, 11, 8);
2540      n = Bits32(opcode, 19, 16);
2541      setflags = false;
2542      uint32_t i = Bit32(opcode, 26);
2543      uint32_t imm3 = Bits32(opcode, 14, 12);
2544      uint32_t imm8 = Bits32(opcode, 7, 0);
2545      imm32 = (i << 11) | (imm3 << 8) | imm8;
2546
2547      // if Rn == '1101' then SEE ADD (SP plus immediate);
2548      if (n == 13)
2549        return EmulateADDSPImm(opcode, eEncodingT4);
2550
2551      // if BadReg(d) then UNPREDICTABLE;
2552      if (BadReg(d))
2553        return false;
2554
2555      break;
2556    }
2557
2558    default:
2559      return false;
2560    }
2561
2562    uint64_t Rn =
2563        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2564    if (!success)
2565      return false;
2566
2567    //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2568    AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
2569
2570    RegisterInfo reg_n;
2571    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2572
2573    EmulateInstruction::Context context;
2574    context.type = eContextArithmetic;
2575    context.SetRegisterPlusOffset(reg_n, imm32);
2576
2577    // R[d] = result;
2578    // if setflags then
2579    // APSR.N = result<31>;
2580    // APSR.Z = IsZeroBit(result);
2581    // APSR.C = carry;
2582    // APSR.V = overflow;
2583    if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
2584                                   res.carry_out, res.overflow))
2585      return false;
2586  }
2587  return true;
2588}
2589
2590// This instruction adds an immediate value to a register value, and writes the
2591// result to the destination
2592// register.  It can optionally update the condition flags based on the result.
2593bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
2594                                             const ARMEncoding encoding) {
2595#if 0
2596    // ARM pseudo code...
2597    if ConditionPassed() then
2598        EncodingSpecificOperations();
2599        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2600        if d == 15 then
2601            ALUWritePC(result); // setflags is always FALSE here
2602        else
2603            R[d] = result;
2604            if setflags then
2605                APSR.N = result<31>;
2606                APSR.Z = IsZeroBit(result);
2607                APSR.C = carry;
2608                APSR.V = overflow;
2609#endif
2610
2611  bool success = false;
2612
2613  if (ConditionPassed(opcode)) {
2614    uint32_t Rd, Rn;
2615    uint32_t
2616        imm32; // the immediate value to be added to the value obtained from Rn
2617    bool setflags;
2618    switch (encoding) {
2619    case eEncodingA1:
2620      Rd = Bits32(opcode, 15, 12);
2621      Rn = Bits32(opcode, 19, 16);
2622      setflags = BitIsSet(opcode, 20);
2623      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2624      break;
2625    default:
2626      return false;
2627    }
2628
2629    // Read the first operand.
2630    uint32_t val1 = ReadCoreReg(Rn, &success);
2631    if (!success)
2632      return false;
2633
2634    AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2635
2636    EmulateInstruction::Context context;
2637    if (Rd == 13)
2638      context.type = EmulateInstruction::eContextAdjustStackPointer;
2639    else if (Rd == GetFramePointerRegisterNumber())
2640      context.type = EmulateInstruction::eContextSetFramePointer;
2641    else
2642      context.type = EmulateInstruction::eContextRegisterPlusOffset;
2643
2644    RegisterInfo dwarf_reg;
2645    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
2646    context.SetRegisterPlusOffset(dwarf_reg, imm32);
2647
2648    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2649                                   res.carry_out, res.overflow))
2650      return false;
2651  }
2652  return true;
2653}
2654
2655// This instruction adds a register value and an optionally-shifted register
2656// value, and writes the result
2657// to the destination register. It can optionally update the condition flags
2658// based on the result.
2659bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
2660                                          const ARMEncoding encoding) {
2661#if 0
2662    // ARM pseudo code...
2663    if ConditionPassed() then
2664        EncodingSpecificOperations();
2665        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2666        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2667        if d == 15 then
2668            ALUWritePC(result); // setflags is always FALSE here
2669        else
2670            R[d] = result;
2671            if setflags then
2672                APSR.N = result<31>;
2673                APSR.Z = IsZeroBit(result);
2674                APSR.C = carry;
2675                APSR.V = overflow;
2676#endif
2677
2678  bool success = false;
2679
2680  if (ConditionPassed(opcode)) {
2681    uint32_t Rd, Rn, Rm;
2682    ARM_ShifterType shift_t;
2683    uint32_t shift_n; // the shift applied to the value read from Rm
2684    bool setflags;
2685    switch (encoding) {
2686    case eEncodingT1:
2687      Rd = Bits32(opcode, 2, 0);
2688      Rn = Bits32(opcode, 5, 3);
2689      Rm = Bits32(opcode, 8, 6);
2690      setflags = !InITBlock();
2691      shift_t = SRType_LSL;
2692      shift_n = 0;
2693      break;
2694    case eEncodingT2:
2695      Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2696      Rm = Bits32(opcode, 6, 3);
2697      setflags = false;
2698      shift_t = SRType_LSL;
2699      shift_n = 0;
2700      if (Rn == 15 && Rm == 15)
2701        return false;
2702      if (Rd == 15 && InITBlock() && !LastInITBlock())
2703        return false;
2704      break;
2705    case eEncodingA1:
2706      Rd = Bits32(opcode, 15, 12);
2707      Rn = Bits32(opcode, 19, 16);
2708      Rm = Bits32(opcode, 3, 0);
2709      setflags = BitIsSet(opcode, 20);
2710      shift_n = DecodeImmShiftARM(opcode, shift_t);
2711      break;
2712    default:
2713      return false;
2714    }
2715
2716    // Read the first operand.
2717    uint32_t val1 = ReadCoreReg(Rn, &success);
2718    if (!success)
2719      return false;
2720
2721    // Read the second operand.
2722    uint32_t val2 = ReadCoreReg(Rm, &success);
2723    if (!success)
2724      return false;
2725
2726    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2727    if (!success)
2728      return false;
2729    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2730
2731    EmulateInstruction::Context context;
2732    context.type = eContextArithmetic;
2733    RegisterInfo op1_reg;
2734    RegisterInfo op2_reg;
2735    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2736    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2737    context.SetRegisterRegisterOperands(op1_reg, op2_reg);
2738
2739    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
2740                                   res.carry_out, res.overflow))
2741      return false;
2742  }
2743  return true;
2744}
2745
2746// Compare Negative (immediate) adds a register value and an immediate value.
2747// It updates the condition flags based on the result, and discards the result.
2748bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
2749                                          const ARMEncoding encoding) {
2750#if 0
2751    // ARM pseudo code...
2752    if ConditionPassed() then
2753        EncodingSpecificOperations();
2754        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2755        APSR.N = result<31>;
2756        APSR.Z = IsZeroBit(result);
2757        APSR.C = carry;
2758        APSR.V = overflow;
2759#endif
2760
2761  bool success = false;
2762
2763  uint32_t Rn;    // the first operand
2764  uint32_t imm32; // the immediate value to be compared with
2765  switch (encoding) {
2766  case eEncodingT1:
2767    Rn = Bits32(opcode, 19, 16);
2768    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2769    if (Rn == 15)
2770      return false;
2771    break;
2772  case eEncodingA1:
2773    Rn = Bits32(opcode, 19, 16);
2774    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2775    break;
2776  default:
2777    return false;
2778  }
2779  // Read the register value from the operand register Rn.
2780  uint32_t reg_val = ReadCoreReg(Rn, &success);
2781  if (!success)
2782    return false;
2783
2784  AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2785
2786  EmulateInstruction::Context context;
2787  context.type = EmulateInstruction::eContextImmediate;
2788  context.SetNoArgs();
2789  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2790    return false;
2791
2792  return true;
2793}
2794
2795// Compare Negative (register) adds a register value and an optionally-shifted
2796// register value.
2797// It updates the condition flags based on the result, and discards the result.
2798bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
2799                                          const ARMEncoding encoding) {
2800#if 0
2801    // ARM pseudo code...
2802    if ConditionPassed() then
2803        EncodingSpecificOperations();
2804        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2805        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2806        APSR.N = result<31>;
2807        APSR.Z = IsZeroBit(result);
2808        APSR.C = carry;
2809        APSR.V = overflow;
2810#endif
2811
2812  bool success = false;
2813
2814  uint32_t Rn; // the first operand
2815  uint32_t Rm; // the second operand
2816  ARM_ShifterType shift_t;
2817  uint32_t shift_n; // the shift applied to the value read from Rm
2818  switch (encoding) {
2819  case eEncodingT1:
2820    Rn = Bits32(opcode, 2, 0);
2821    Rm = Bits32(opcode, 5, 3);
2822    shift_t = SRType_LSL;
2823    shift_n = 0;
2824    break;
2825  case eEncodingT2:
2826    Rn = Bits32(opcode, 19, 16);
2827    Rm = Bits32(opcode, 3, 0);
2828    shift_n = DecodeImmShiftThumb(opcode, shift_t);
2829    // if n == 15 || BadReg(m) then UNPREDICTABLE;
2830    if (Rn == 15 || BadReg(Rm))
2831      return false;
2832    break;
2833  case eEncodingA1:
2834    Rn = Bits32(opcode, 19, 16);
2835    Rm = Bits32(opcode, 3, 0);
2836    shift_n = DecodeImmShiftARM(opcode, shift_t);
2837    break;
2838  default:
2839    return false;
2840  }
2841  // Read the register value from register Rn.
2842  uint32_t val1 = ReadCoreReg(Rn, &success);
2843  if (!success)
2844    return false;
2845
2846  // Read the register value from register Rm.
2847  uint32_t val2 = ReadCoreReg(Rm, &success);
2848  if (!success)
2849    return false;
2850
2851  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2852  if (!success)
2853    return false;
2854  AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2855
2856  EmulateInstruction::Context context;
2857  context.type = EmulateInstruction::eContextImmediate;
2858  context.SetNoArgs();
2859  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2860    return false;
2861
2862  return true;
2863}
2864
2865// Compare (immediate) subtracts an immediate value from a register value.
2866// It updates the condition flags based on the result, and discards the result.
2867bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
2868                                          const ARMEncoding encoding) {
2869#if 0
2870    // ARM pseudo code...
2871    if ConditionPassed() then
2872        EncodingSpecificOperations();
2873        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2874        APSR.N = result<31>;
2875        APSR.Z = IsZeroBit(result);
2876        APSR.C = carry;
2877        APSR.V = overflow;
2878#endif
2879
2880  bool success = false;
2881
2882  uint32_t Rn;    // the first operand
2883  uint32_t imm32; // the immediate value to be compared with
2884  switch (encoding) {
2885  case eEncodingT1:
2886    Rn = Bits32(opcode, 10, 8);
2887    imm32 = Bits32(opcode, 7, 0);
2888    break;
2889  case eEncodingT2:
2890    Rn = Bits32(opcode, 19, 16);
2891    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2892    if (Rn == 15)
2893      return false;
2894    break;
2895  case eEncodingA1:
2896    Rn = Bits32(opcode, 19, 16);
2897    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2898    break;
2899  default:
2900    return false;
2901  }
2902  // Read the register value from the operand register Rn.
2903  uint32_t reg_val = ReadCoreReg(Rn, &success);
2904  if (!success)
2905    return false;
2906
2907  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2908
2909  EmulateInstruction::Context context;
2910  context.type = EmulateInstruction::eContextImmediate;
2911  context.SetNoArgs();
2912  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2913    return false;
2914
2915  return true;
2916}
2917
2918// Compare (register) subtracts an optionally-shifted register value from a
2919// register value.
2920// It updates the condition flags based on the result, and discards the result.
2921bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
2922                                          const ARMEncoding encoding) {
2923#if 0
2924    // ARM pseudo code...
2925    if ConditionPassed() then
2926        EncodingSpecificOperations();
2927        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2928        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2929        APSR.N = result<31>;
2930        APSR.Z = IsZeroBit(result);
2931        APSR.C = carry;
2932        APSR.V = overflow;
2933#endif
2934
2935  bool success = false;
2936
2937  uint32_t Rn; // the first operand
2938  uint32_t Rm; // the second operand
2939  ARM_ShifterType shift_t;
2940  uint32_t shift_n; // the shift applied to the value read from Rm
2941  switch (encoding) {
2942  case eEncodingT1:
2943    Rn = Bits32(opcode, 2, 0);
2944    Rm = Bits32(opcode, 5, 3);
2945    shift_t = SRType_LSL;
2946    shift_n = 0;
2947    break;
2948  case eEncodingT2:
2949    Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2950    Rm = Bits32(opcode, 6, 3);
2951    shift_t = SRType_LSL;
2952    shift_n = 0;
2953    if (Rn < 8 && Rm < 8)
2954      return false;
2955    if (Rn == 15 || Rm == 15)
2956      return false;
2957    break;
2958  case eEncodingT3:
2959    Rn = Bits32(opcode, 19, 16);
2960    Rm = Bits32(opcode, 3, 0);
2961    shift_n = DecodeImmShiftThumb(opcode, shift_t);
2962    if (Rn == 15 || BadReg(Rm))
2963      return false;
2964    break;
2965  case eEncodingA1:
2966    Rn = Bits32(opcode, 19, 16);
2967    Rm = Bits32(opcode, 3, 0);
2968    shift_n = DecodeImmShiftARM(opcode, shift_t);
2969    break;
2970  default:
2971    return false;
2972  }
2973  // Read the register value from register Rn.
2974  uint32_t val1 = ReadCoreReg(Rn, &success);
2975  if (!success)
2976    return false;
2977
2978  // Read the register value from register Rm.
2979  uint32_t val2 = ReadCoreReg(Rm, &success);
2980  if (!success)
2981    return false;
2982
2983  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2984  if (!success)
2985    return false;
2986  AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2987
2988  EmulateInstruction::Context context;
2989  context.type = EmulateInstruction::eContextImmediate;
2990  context.SetNoArgs();
2991  if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2992    return false;
2993
2994  return true;
2995}
2996
2997// Arithmetic Shift Right (immediate) shifts a register value right by an
2998// immediate number of bits,
2999// shifting in copies of its sign bit, and writes the result to the destination
3000// register.  It can
3001// optionally update the condition flags based on the result.
3002bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
3003                                          const ARMEncoding encoding) {
3004#if 0
3005    // ARM pseudo code...
3006    if ConditionPassed() then
3007        EncodingSpecificOperations();
3008        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3009        if d == 15 then         // Can only occur for ARM encoding
3010            ALUWritePC(result); // setflags is always FALSE here
3011        else
3012            R[d] = result;
3013            if setflags then
3014                APSR.N = result<31>;
3015                APSR.Z = IsZeroBit(result);
3016                APSR.C = carry;
3017                // APSR.V unchanged
3018#endif
3019
3020  return EmulateShiftImm(opcode, encoding, SRType_ASR);
3021}
3022
3023// Arithmetic Shift Right (register) shifts a register value right by a variable
3024// number of bits,
3025// shifting in copies of its sign bit, and writes the result to the destination
3026// register.
3027// The variable number of bits is read from the bottom byte of a register. It
3028// can optionally update
3029// the condition flags based on the result.
3030bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
3031                                          const ARMEncoding encoding) {
3032#if 0
3033    // ARM pseudo code...
3034    if ConditionPassed() then
3035        EncodingSpecificOperations();
3036        shift_n = UInt(R[m]<7:0>);
3037        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3038        R[d] = result;
3039        if setflags then
3040            APSR.N = result<31>;
3041            APSR.Z = IsZeroBit(result);
3042            APSR.C = carry;
3043            // APSR.V unchanged
3044#endif
3045
3046  return EmulateShiftReg(opcode, encoding, SRType_ASR);
3047}
3048
3049// Logical Shift Left (immediate) shifts a register value left by an immediate
3050// number of bits,
3051// shifting in zeros, and writes the result to the destination register.  It can
3052// optionally
3053// update the condition flags based on the result.
3054bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
3055                                          const ARMEncoding encoding) {
3056#if 0
3057    // ARM pseudo code...
3058    if ConditionPassed() then
3059        EncodingSpecificOperations();
3060        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3061        if d == 15 then         // Can only occur for ARM encoding
3062            ALUWritePC(result); // setflags is always FALSE here
3063        else
3064            R[d] = result;
3065            if setflags then
3066                APSR.N = result<31>;
3067                APSR.Z = IsZeroBit(result);
3068                APSR.C = carry;
3069                // APSR.V unchanged
3070#endif
3071
3072  return EmulateShiftImm(opcode, encoding, SRType_LSL);
3073}
3074
3075// Logical Shift Left (register) shifts a register value left by a variable
3076// number of bits,
3077// shifting in zeros, and writes the result to the destination register.  The
3078// variable number
3079// of bits is read from the bottom byte of a register. It can optionally update
3080// the condition
3081// flags based on the result.
3082bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
3083                                          const ARMEncoding encoding) {
3084#if 0
3085    // ARM pseudo code...
3086    if ConditionPassed() then
3087        EncodingSpecificOperations();
3088        shift_n = UInt(R[m]<7:0>);
3089        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3090        R[d] = result;
3091        if setflags then
3092            APSR.N = result<31>;
3093            APSR.Z = IsZeroBit(result);
3094            APSR.C = carry;
3095            // APSR.V unchanged
3096#endif
3097
3098  return EmulateShiftReg(opcode, encoding, SRType_LSL);
3099}
3100
3101// Logical Shift Right (immediate) shifts a register value right by an immediate
3102// number of bits,
3103// shifting in zeros, and writes the result to the destination register.  It can
3104// optionally
3105// update the condition flags based on the result.
3106bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
3107                                          const ARMEncoding encoding) {
3108#if 0
3109    // ARM pseudo code...
3110    if ConditionPassed() then
3111        EncodingSpecificOperations();
3112        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3113        if d == 15 then         // Can only occur for ARM encoding
3114            ALUWritePC(result); // setflags is always FALSE here
3115        else
3116            R[d] = result;
3117            if setflags then
3118                APSR.N = result<31>;
3119                APSR.Z = IsZeroBit(result);
3120                APSR.C = carry;
3121                // APSR.V unchanged
3122#endif
3123
3124  return EmulateShiftImm(opcode, encoding, SRType_LSR);
3125}
3126
3127// Logical Shift Right (register) shifts a register value right by a variable
3128// number of bits,
3129// shifting in zeros, and writes the result to the destination register.  The
3130// variable number
3131// of bits is read from the bottom byte of a register. It can optionally update
3132// the condition
3133// flags based on the result.
3134bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
3135                                          const ARMEncoding encoding) {
3136#if 0
3137    // ARM pseudo code...
3138    if ConditionPassed() then
3139        EncodingSpecificOperations();
3140        shift_n = UInt(R[m]<7:0>);
3141        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3142        R[d] = result;
3143        if setflags then
3144            APSR.N = result<31>;
3145            APSR.Z = IsZeroBit(result);
3146            APSR.C = carry;
3147            // APSR.V unchanged
3148#endif
3149
3150  return EmulateShiftReg(opcode, encoding, SRType_LSR);
3151}
3152
3153// Rotate Right (immediate) provides the value of the contents of a register
3154// rotated by a constant value.
3155// The bits that are rotated off the right end are inserted into the vacated bit
3156// positions on the left.
3157// It can optionally update the condition flags based on the result.
3158bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
3159                                          const ARMEncoding encoding) {
3160#if 0
3161    // ARM pseudo code...
3162    if ConditionPassed() then
3163        EncodingSpecificOperations();
3164        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3165        if d == 15 then         // Can only occur for ARM encoding
3166            ALUWritePC(result); // setflags is always FALSE here
3167        else
3168            R[d] = result;
3169            if setflags then
3170                APSR.N = result<31>;
3171                APSR.Z = IsZeroBit(result);
3172                APSR.C = carry;
3173                // APSR.V unchanged
3174#endif
3175
3176  return EmulateShiftImm(opcode, encoding, SRType_ROR);
3177}
3178
3179// Rotate Right (register) provides the value of the contents of a register
3180// rotated by a variable number of bits.
3181// The bits that are rotated off the right end are inserted into the vacated bit
3182// positions on the left.
3183// The variable number of bits is read from the bottom byte of a register. It
3184// can optionally update the condition
3185// flags based on the result.
3186bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
3187                                          const ARMEncoding encoding) {
3188#if 0
3189    // ARM pseudo code...
3190    if ConditionPassed() then
3191        EncodingSpecificOperations();
3192        shift_n = UInt(R[m]<7:0>);
3193        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3194        R[d] = result;
3195        if setflags then
3196            APSR.N = result<31>;
3197            APSR.Z = IsZeroBit(result);
3198            APSR.C = carry;
3199            // APSR.V unchanged
3200#endif
3201
3202  return EmulateShiftReg(opcode, encoding, SRType_ROR);
3203}
3204
3205// Rotate Right with Extend provides the value of the contents of a register
3206// shifted right by one place,
3207// with the carry flag shifted into bit [31].
3208//
3209// RRX can optionally update the condition flags based on the result.
3210// In that case, bit [0] is shifted into the carry flag.
3211bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
3212                                       const ARMEncoding encoding) {
3213#if 0
3214    // ARM pseudo code...
3215    if ConditionPassed() then
3216        EncodingSpecificOperations();
3217        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3218        if d == 15 then         // Can only occur for ARM encoding
3219            ALUWritePC(result); // setflags is always FALSE here
3220        else
3221            R[d] = result;
3222            if setflags then
3223                APSR.N = result<31>;
3224                APSR.Z = IsZeroBit(result);
3225                APSR.C = carry;
3226                // APSR.V unchanged
3227#endif
3228
3229  return EmulateShiftImm(opcode, encoding, SRType_RRX);
3230}
3231
3232bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
3233                                            const ARMEncoding encoding,
3234                                            ARM_ShifterType shift_type) {
3235  //    assert(shift_type == SRType_ASR
3236  //           || shift_type == SRType_LSL
3237  //           || shift_type == SRType_LSR
3238  //           || shift_type == SRType_ROR
3239  //           || shift_type == SRType_RRX);
3240
3241  bool success = false;
3242
3243  if (ConditionPassed(opcode)) {
3244    uint32_t Rd;    // the destination register
3245    uint32_t Rm;    // the first operand register
3246    uint32_t imm5;  // encoding for the shift amount
3247    uint32_t carry; // the carry bit after the shift operation
3248    bool setflags;
3249
3250    // Special case handling!
3251    // A8.6.139 ROR (immediate) -- Encoding T1
3252    ARMEncoding use_encoding = encoding;
3253    if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
3254      // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding
3255      // to
3256      // have the same decoding of bit fields as the other Thumb2 shift
3257      // operations.
3258      use_encoding = eEncodingT2;
3259    }
3260
3261    switch (use_encoding) {
3262    case eEncodingT1:
3263      // Due to the above special case handling!
3264      if (shift_type == SRType_ROR)
3265        return false;
3266
3267      Rd = Bits32(opcode, 2, 0);
3268      Rm = Bits32(opcode, 5, 3);
3269      setflags = !InITBlock();
3270      imm5 = Bits32(opcode, 10, 6);
3271      break;
3272    case eEncodingT2:
3273      // A8.6.141 RRX
3274      // There's no imm form of RRX instructions.
3275      if (shift_type == SRType_RRX)
3276        return false;
3277
3278      Rd = Bits32(opcode, 11, 8);
3279      Rm = Bits32(opcode, 3, 0);
3280      setflags = BitIsSet(opcode, 20);
3281      imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3282      if (BadReg(Rd) || BadReg(Rm))
3283        return false;
3284      break;
3285    case eEncodingA1:
3286      Rd = Bits32(opcode, 15, 12);
3287      Rm = Bits32(opcode, 3, 0);
3288      setflags = BitIsSet(opcode, 20);
3289      imm5 = Bits32(opcode, 11, 7);
3290      break;
3291    default:
3292      return false;
3293    }
3294
3295    // A8.6.139 ROR (immediate)
3296    if (shift_type == SRType_ROR && imm5 == 0)
3297      shift_type = SRType_RRX;
3298
3299    // Get the first operand.
3300    uint32_t value = ReadCoreReg(Rm, &success);
3301    if (!success)
3302      return false;
3303
3304    // Decode the shift amount if not RRX.
3305    uint32_t amt =
3306        (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3307
3308    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3309    if (!success)
3310      return false;
3311
3312    // The context specifies that an immediate is to be moved into Rd.
3313    EmulateInstruction::Context context;
3314    context.type = EmulateInstruction::eContextImmediate;
3315    context.SetNoArgs();
3316
3317    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3318      return false;
3319  }
3320  return true;
3321}
3322
3323bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
3324                                            const ARMEncoding encoding,
3325                                            ARM_ShifterType shift_type) {
3326  // assert(shift_type == SRType_ASR
3327  //        || shift_type == SRType_LSL
3328  //        || shift_type == SRType_LSR
3329  //        || shift_type == SRType_ROR);
3330
3331  bool success = false;
3332
3333  if (ConditionPassed(opcode)) {
3334    uint32_t Rd; // the destination register
3335    uint32_t Rn; // the first operand register
3336    uint32_t
3337        Rm; // the register whose bottom byte contains the amount to shift by
3338    uint32_t carry; // the carry bit after the shift operation
3339    bool setflags;
3340    switch (encoding) {
3341    case eEncodingT1:
3342      Rd = Bits32(opcode, 2, 0);
3343      Rn = Rd;
3344      Rm = Bits32(opcode, 5, 3);
3345      setflags = !InITBlock();
3346      break;
3347    case eEncodingT2:
3348      Rd = Bits32(opcode, 11, 8);
3349      Rn = Bits32(opcode, 19, 16);
3350      Rm = Bits32(opcode, 3, 0);
3351      setflags = BitIsSet(opcode, 20);
3352      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3353        return false;
3354      break;
3355    case eEncodingA1:
3356      Rd = Bits32(opcode, 15, 12);
3357      Rn = Bits32(opcode, 3, 0);
3358      Rm = Bits32(opcode, 11, 8);
3359      setflags = BitIsSet(opcode, 20);
3360      if (Rd == 15 || Rn == 15 || Rm == 15)
3361        return false;
3362      break;
3363    default:
3364      return false;
3365    }
3366
3367    // Get the first operand.
3368    uint32_t value = ReadCoreReg(Rn, &success);
3369    if (!success)
3370      return false;
3371    // Get the Rm register content.
3372    uint32_t val = ReadCoreReg(Rm, &success);
3373    if (!success)
3374      return false;
3375
3376    // Get the shift amount.
3377    uint32_t amt = Bits32(val, 7, 0);
3378
3379    uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3380    if (!success)
3381      return false;
3382
3383    // The context specifies that an immediate is to be moved into Rd.
3384    EmulateInstruction::Context context;
3385    context.type = EmulateInstruction::eContextImmediate;
3386    context.SetNoArgs();
3387
3388    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3389      return false;
3390  }
3391  return true;
3392}
3393
3394// LDM loads multiple registers from consecutive memory locations, using an
3395// address from a base register.  Optionally the address just above the highest
3396// of those locations
3397// can be written back to the base register.
3398bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
3399                                       const ARMEncoding encoding) {
3400#if 0
3401    // ARM pseudo code...
3402    if ConditionPassed()
3403        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3404        address = R[n];
3405
3406        for i = 0 to 14
3407            if registers<i> == '1' then
3408                R[i] = MemA[address, 4]; address = address + 4;
3409        if registers<15> == '1' then
3410            LoadWritePC (MemA[address, 4]);
3411
3412        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3413        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3414
3415#endif
3416
3417  bool success = false;
3418  if (ConditionPassed(opcode)) {
3419    uint32_t n;
3420    uint32_t registers = 0;
3421    bool wback;
3422    const uint32_t addr_byte_size = GetAddressByteSize();
3423    switch (encoding) {
3424    case eEncodingT1:
3425      // n = UInt(Rn); registers = '00000000':register_list; wback =
3426      // (registers<n> == '0');
3427      n = Bits32(opcode, 10, 8);
3428      registers = Bits32(opcode, 7, 0);
3429      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
3430      wback = BitIsClear(registers, n);
3431      // if BitCount(registers) < 1 then UNPREDICTABLE;
3432      if (BitCount(registers) < 1)
3433        return false;
3434      break;
3435    case eEncodingT2:
3436      // if W == '1' && Rn == '1101' then SEE POP;
3437      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3438      n = Bits32(opcode, 19, 16);
3439      registers = Bits32(opcode, 15, 0);
3440      registers = registers & 0xdfff; // Make sure bit 13 is zero.
3441      wback = BitIsSet(opcode, 21);
3442
3443      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3444      // UNPREDICTABLE;
3445      if ((n == 15) || (BitCount(registers) < 2) ||
3446          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3447        return false;
3448
3449      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3450      // UNPREDICTABLE;
3451      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3452        return false;
3453
3454      // if wback && registers<n> == '1' then UNPREDICTABLE;
3455      if (wback && BitIsSet(registers, n))
3456        return false;
3457      break;
3458
3459    case eEncodingA1:
3460      n = Bits32(opcode, 19, 16);
3461      registers = Bits32(opcode, 15, 0);
3462      wback = BitIsSet(opcode, 21);
3463      if ((n == 15) || (BitCount(registers) < 1))
3464        return false;
3465      break;
3466    default:
3467      return false;
3468    }
3469
3470    int32_t offset = 0;
3471    const addr_t base_address =
3472        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3473    if (!success)
3474      return false;
3475
3476    EmulateInstruction::Context context;
3477    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3478    RegisterInfo dwarf_reg;
3479    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3480    context.SetRegisterPlusOffset(dwarf_reg, offset);
3481
3482    for (int i = 0; i < 14; ++i) {
3483      if (BitIsSet(registers, i)) {
3484        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3485        context.SetRegisterPlusOffset(dwarf_reg, offset);
3486        if (wback && (n == 13)) // Pop Instruction
3487        {
3488          context.type = EmulateInstruction::eContextPopRegisterOffStack;
3489          context.SetAddress(base_address + offset);
3490        }
3491
3492        // R[i] = MemA [address, 4]; address = address + 4;
3493        uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
3494                                 0, &success);
3495        if (!success)
3496          return false;
3497
3498        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
3499                                   data))
3500          return false;
3501
3502        offset += addr_byte_size;
3503      }
3504    }
3505
3506    if (BitIsSet(registers, 15)) {
3507      // LoadWritePC (MemA [address, 4]);
3508      context.type = EmulateInstruction::eContextRegisterPlusOffset;
3509      context.SetRegisterPlusOffset(dwarf_reg, offset);
3510      uint32_t data =
3511          MemARead(context, base_address + offset, addr_byte_size, 0, &success);
3512      if (!success)
3513        return false;
3514      // In ARMv5T and above, this is an interworking branch.
3515      if (!LoadWritePC(context, data))
3516        return false;
3517    }
3518
3519    if (wback && BitIsClear(registers, n)) {
3520      // R[n] = R[n] + 4 * BitCount (registers)
3521      int32_t offset = addr_byte_size * BitCount(registers);
3522      context.type = EmulateInstruction::eContextAdjustBaseRegister;
3523      context.SetRegisterPlusOffset(dwarf_reg, offset);
3524
3525      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
3526                                 base_address + offset))
3527        return false;
3528    }
3529    if (wback && BitIsSet(registers, n))
3530      // R[n] bits(32) UNKNOWN;
3531      return WriteBits32Unknown(n);
3532  }
3533  return true;
3534}
3535
3536// LDMDA loads multiple registers from consecutive memory locations using an
3537// address from a base register.
3538// The consecutive memory locations end at this address and the address just
3539// below the lowest of those locations
3540// can optionally be written back to the base register.
3541bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
3542                                         const ARMEncoding encoding) {
3543#if 0
3544    // ARM pseudo code...
3545    if ConditionPassed() then
3546        EncodingSpecificOperations();
3547        address = R[n] - 4*BitCount(registers) + 4;
3548
3549        for i = 0 to 14
3550            if registers<i> == '1' then
3551                  R[i] = MemA[address,4]; address = address + 4;
3552
3553        if registers<15> == '1' then
3554            LoadWritePC(MemA[address,4]);
3555
3556        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3557        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3558#endif
3559
3560  bool success = false;
3561
3562  if (ConditionPassed(opcode)) {
3563    uint32_t n;
3564    uint32_t registers = 0;
3565    bool wback;
3566    const uint32_t addr_byte_size = GetAddressByteSize();
3567
3568    // EncodingSpecificOperations();
3569    switch (encoding) {
3570    case eEncodingA1:
3571      // n = UInt(Rn); registers = register_list; wback = (W == '1');
3572      n = Bits32(opcode, 19, 16);
3573      registers = Bits32(opcode, 15, 0);
3574      wback = BitIsSet(opcode, 21);
3575
3576      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3577      if ((n == 15) || (BitCount(registers) < 1))
3578        return false;
3579
3580      break;
3581
3582    default:
3583      return false;
3584    }
3585    // address = R[n] - 4*BitCount(registers) + 4;
3586
3587    int32_t offset = 0;
3588    addr_t Rn = ReadCoreReg(n, &success);
3589
3590    if (!success)
3591      return false;
3592
3593    addr_t address =
3594        Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
3595
3596    EmulateInstruction::Context context;
3597    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3598    RegisterInfo dwarf_reg;
3599    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3600    context.SetRegisterPlusOffset(dwarf_reg, offset);
3601
3602    // for i = 0 to 14
3603    for (int i = 0; i < 14; ++i) {
3604      // if registers<i> == '1' then
3605      if (BitIsSet(registers, i)) {
3606        // R[i] = MemA[address,4]; address = address + 4;
3607        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
3608        uint32_t data =
3609            MemARead(context, address + offset, addr_byte_size, 0, &success);
3610        if (!success)
3611          return false;
3612        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
3613                                   data))
3614          return false;
3615        offset += addr_byte_size;
3616      }
3617    }
3618
3619    // if registers<15> == '1' then
3620    //     LoadWritePC(MemA[address,4]);
3621    if (BitIsSet(registers, 15)) {
3622      context.SetRegisterPlusOffset(dwarf_reg, offset);
3623      uint32_t data =
3624          MemARead(context, address + offset, addr_byte_size, 0, &success);
3625      if (!success)
3626        return false;
3627      // In ARMv5T and above, this is an interworking branch.
3628      if (!LoadWritePC(context, data))
3629        return false;
3630    }
3631
3632    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3633    if (wback && BitIsClear(registers, n)) {
3634      if (!success)
3635        return false;
3636
3637      offset = (addr_byte_size * BitCount(registers)) * -1;
3638      context.type = EmulateInstruction::eContextAdjustBaseRegister;
3639      context.SetImmediateSigned(offset);
3640      addr_t addr = Rn + offset;
3641      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
3642                                 addr))
3643        return false;
3644    }
3645
3646    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3647    if (wback && BitIsSet(registers, n))
3648      return WriteBits32Unknown(n);
3649  }
3650  return true;
3651}
3652
3653// LDMDB loads multiple registers from consecutive memory locations using an
3654// address from a base register.  The
3655// consecutive memory locations end just below this address, and the address of
3656// the lowest of those locations can
3657// be optionally written back to the base register.
3658bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
3659                                         const ARMEncoding encoding) {
3660#if 0
3661    // ARM pseudo code...
3662    if ConditionPassed() then
3663        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3664        address = R[n] - 4*BitCount(registers);
3665
3666        for i = 0 to 14
3667            if registers<i> == '1' then
3668                  R[i] = MemA[address,4]; address = address + 4;
3669        if registers<15> == '1' then
3670                  LoadWritePC(MemA[address,4]);
3671
3672        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3673        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3674#endif
3675
3676  bool success = false;
3677
3678  if (ConditionPassed(opcode)) {
3679    uint32_t n;
3680    uint32_t registers = 0;
3681    bool wback;
3682    const uint32_t addr_byte_size = GetAddressByteSize();
3683    switch (encoding) {
3684    case eEncodingT1:
3685      // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3686      n = Bits32(opcode, 19, 16);
3687      registers = Bits32(opcode, 15, 0);
3688      registers = registers & 0xdfff; // Make sure bit 13 is a zero.
3689      wback = BitIsSet(opcode, 21);
3690
3691      // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
3692      // UNPREDICTABLE;
3693      if ((n == 15) || (BitCount(registers) < 2) ||
3694          (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
3695        return false;
3696
3697      // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
3698      // UNPREDICTABLE;
3699      if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
3700        return false;
3701
3702      // if wback && registers<n> == '1' then UNPREDICTABLE;
3703      if (wback && BitIsSet(registers, n))
3704        return false;
3705
3706      break;
3707
3708    case eEncodingA1:
3709      // n = UInt(Rn); registers = register_list; wback = (W == '1');
3710      n = Bits32(opcode, 19, 16);
3711      registers = Bits32(opcode, 15, 0);
3712      wback = BitIsSet(opcode, 21);
3713
3714      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3715      if ((n == 15) || (BitCount(registers) < 1))
3716        return false;
3717
3718      break;
3719
3720    default:
3721      return false;
3722    }
3723
3724    // address = R[n] - 4*BitCount(registers);
3725
3726    int32_t offset = 0;
3727    addr_t Rn =
3728        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3729
3730    if (!success)
3731      return false;
3732
3733    addr_t address = Rn - (addr_byte_size * BitCount(registers));
3734    EmulateInstruction::Context context;
3735    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3736    RegisterInfo dwarf_reg;
3737    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3738    context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
3739
3740    for (int i = 0; i < 14; ++i) {
3741      if (BitIsSet(registers, i)) {
3742        // R[i] = MemA[address,4]; address = address + 4;
3743        context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
3744        uint32_t data =
3745            MemARead(context, address + offset, addr_byte_size, 0, &success);
3746        if (!success)
3747          return false;
3748
3749        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
3750                                   data))
3751          return false;
3752
3753        offset += addr_byte_size;
3754      }
3755    }
3756
3757    // if registers<15> == '1' then
3758    //     LoadWritePC(MemA[address,4]);
3759    if (BitIsSet(registers, 15)) {
3760      context.SetRegisterPlusOffset(dwarf_reg, offset);
3761      uint32_t data =
3762          MemARead(context, address + offset, addr_byte_size, 0, &success);
3763      if (!success)
3764        return false;
3765      // In ARMv5T and above, this is an interworking branch.
3766      if (!LoadWritePC(context, data))
3767        return false;
3768    }
3769
3770    // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3771    if (wback && BitIsClear(registers, n)) {
3772      if (!success)
3773        return false;
3774
3775      offset = (addr_byte_size * BitCount(registers)) * -1;
3776      context.type = EmulateInstruction::eContextAdjustBaseRegister;
3777      context.SetImmediateSigned(offset);
3778      addr_t addr = Rn + offset;
3779      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
3780                                 addr))
3781        return false;
3782    }
3783
3784    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
3785    // possible for encoding A1
3786    if (wback && BitIsSet(registers, n))
3787      return WriteBits32Unknown(n);
3788  }
3789  return true;
3790}
3791
3792// LDMIB loads multiple registers from consecutive memory locations using an
3793// address from a base register.  The
3794// consecutive memory locations start just above this address, and thea ddress
3795// of the last of those locations can
3796// optinoally be written back to the base register.
3797bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
3798                                         const ARMEncoding encoding) {
3799#if 0
3800    if ConditionPassed() then
3801        EncodingSpecificOperations();
3802        address = R[n] + 4;
3803
3804        for i = 0 to 14
3805            if registers<i> == '1' then
3806                  R[i] = MemA[address,4]; address = address + 4;
3807        if registers<15> == '1' then
3808            LoadWritePC(MemA[address,4]);
3809
3810        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3811        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3812#endif
3813
3814  bool success = false;
3815
3816  if (ConditionPassed(opcode)) {
3817    uint32_t n;
3818    uint32_t registers = 0;
3819    bool wback;
3820    const uint32_t addr_byte_size = GetAddressByteSize();
3821    switch (encoding) {
3822    case eEncodingA1:
3823      // n = UInt(Rn); registers = register_list; wback = (W == '1');
3824      n = Bits32(opcode, 19, 16);
3825      registers = Bits32(opcode, 15, 0);
3826      wback = BitIsSet(opcode, 21);
3827
3828      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3829      if ((n == 15) || (BitCount(registers) < 1))
3830        return false;
3831
3832      break;
3833    default:
3834      return false;
3835    }
3836    // address = R[n] + 4;
3837
3838    int32_t offset = 0;
3839    addr_t Rn =
3840        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3841
3842    if (!success)
3843      return false;
3844
3845    addr_t address = Rn + addr_byte_size;
3846
3847    EmulateInstruction::Context context;
3848    context.type = EmulateInstruction::eContextRegisterPlusOffset;
3849    RegisterInfo dwarf_reg;
3850    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3851    context.SetRegisterPlusOffset(dwarf_reg, offset);
3852
3853    for (int i = 0; i < 14; ++i) {
3854      if (BitIsSet(registers, i)) {
3855        // R[i] = MemA[address,4]; address = address + 4;
3856
3857        context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
3858        uint32_t data =
3859            MemARead(context, address + offset, addr_byte_size, 0, &success);
3860        if (!success)
3861          return false;
3862
3863        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
3864                                   data))
3865          return false;
3866
3867        offset += addr_byte_size;
3868      }
3869    }
3870
3871    // if registers<15> == '1' then
3872    //     LoadWritePC(MemA[address,4]);
3873    if (BitIsSet(registers, 15)) {
3874      context.SetRegisterPlusOffset(dwarf_reg, offset);
3875      uint32_t data =
3876          MemARead(context, address + offset, addr_byte_size, 0, &success);
3877      if (!success)
3878        return false;
3879      // In ARMv5T and above, this is an interworking branch.
3880      if (!LoadWritePC(context, data))
3881        return false;
3882    }
3883
3884    // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3885    if (wback && BitIsClear(registers, n)) {
3886      if (!success)
3887        return false;
3888
3889      offset = addr_byte_size * BitCount(registers);
3890      context.type = EmulateInstruction::eContextAdjustBaseRegister;
3891      context.SetImmediateSigned(offset);
3892      addr_t addr = Rn + offset;
3893      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
3894                                 addr))
3895        return false;
3896    }
3897
3898    // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
3899    // possible for encoding A1
3900    if (wback && BitIsSet(registers, n))
3901      return WriteBits32Unknown(n);
3902  }
3903  return true;
3904}
3905
3906// Load Register (immediate) calculates an address from a base register value
3907// and
3908// an immediate offset, loads a word from memory, and writes to a register.
3909// LDR (immediate, Thumb)
3910bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
3911                                              const ARMEncoding encoding) {
3912#if 0
3913    // ARM pseudo code...
3914    if (ConditionPassed())
3915    {
3916        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3917        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3918        address = if index then offset_addr else R[n];
3919        data = MemU[address,4];
3920        if wback then R[n] = offset_addr;
3921        if t == 15 then
3922            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3923        elsif UnalignedSupport() || address<1:0> = '00' then
3924            R[t] = data;
3925        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3926    }
3927#endif
3928
3929  bool success = false;
3930
3931  if (ConditionPassed(opcode)) {
3932    uint32_t Rt;        // the destination register
3933    uint32_t Rn;        // the base register
3934    uint32_t imm32;     // the immediate offset used to form the address
3935    addr_t offset_addr; // the offset address
3936    addr_t address;     // the calculated address
3937    uint32_t data;      // the literal data value from memory load
3938    bool add, index, wback;
3939    switch (encoding) {
3940    case eEncodingT1:
3941      Rt = Bits32(opcode, 2, 0);
3942      Rn = Bits32(opcode, 5, 3);
3943      imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3944      // index = TRUE; add = TRUE; wback = FALSE
3945      add = true;
3946      index = true;
3947      wback = false;
3948
3949      break;
3950
3951    case eEncodingT2:
3952      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3953      Rt = Bits32(opcode, 10, 8);
3954      Rn = 13;
3955      imm32 = Bits32(opcode, 7, 0) << 2;
3956
3957      // index = TRUE; add = TRUE; wback = FALSE;
3958      index = true;
3959      add = true;
3960      wback = false;
3961
3962      break;
3963
3964    case eEncodingT3:
3965      // if Rn == '1111' then SEE LDR (literal);
3966      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3967      Rt = Bits32(opcode, 15, 12);
3968      Rn = Bits32(opcode, 19, 16);
3969      imm32 = Bits32(opcode, 11, 0);
3970
3971      // index = TRUE; add = TRUE; wback = FALSE;
3972      index = true;
3973      add = true;
3974      wback = false;
3975
3976      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3977      if ((Rt == 15) && InITBlock() && !LastInITBlock())
3978        return false;
3979
3980      break;
3981
3982    case eEncodingT4:
3983      // if Rn == '1111' then SEE LDR (literal);
3984      // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3985      // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
3986      // '00000100' then SEE POP;
3987      // if P == '0' && W == '0' then UNDEFINED;
3988      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
3989        return false;
3990
3991      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3992      Rt = Bits32(opcode, 15, 12);
3993      Rn = Bits32(opcode, 19, 16);
3994      imm32 = Bits32(opcode, 7, 0);
3995
3996      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3997      index = BitIsSet(opcode, 10);
3998      add = BitIsSet(opcode, 9);
3999      wback = BitIsSet(opcode, 8);
4000
4001      // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
4002      // then UNPREDICTABLE;
4003      if ((wback && (Rn == Rt)) ||
4004          ((Rt == 15) && InITBlock() && !LastInITBlock()))
4005        return false;
4006
4007      break;
4008
4009    default:
4010      return false;
4011    }
4012    uint32_t base = ReadCoreReg(Rn, &success);
4013    if (!success)
4014      return false;
4015    if (add)
4016      offset_addr = base + imm32;
4017    else
4018      offset_addr = base - imm32;
4019
4020    address = (index ? offset_addr : base);
4021
4022    RegisterInfo base_reg;
4023    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4024    if (wback) {
4025      EmulateInstruction::Context ctx;
4026      if (Rn == 13) {
4027        ctx.type = eContextAdjustStackPointer;
4028        ctx.SetImmediateSigned((int32_t)(offset_addr - base));
4029      } else if (Rn == GetFramePointerRegisterNumber()) {
4030        ctx.type = eContextSetFramePointer;
4031        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4032      } else {
4033        ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4034        ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4035      }
4036
4037      if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
4038                                 offset_addr))
4039        return false;
4040    }
4041
4042    // Prepare to write to the Rt register.
4043    EmulateInstruction::Context context;
4044    context.type = EmulateInstruction::eContextRegisterLoad;
4045    context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
4046
4047    // Read memory from the address.
4048    data = MemURead(context, address, 4, 0, &success);
4049    if (!success)
4050      return false;
4051
4052    if (Rt == 15) {
4053      if (Bits32(address, 1, 0) == 0) {
4054        if (!LoadWritePC(context, data))
4055          return false;
4056      } else
4057        return false;
4058    } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
4059      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
4060                                 data))
4061        return false;
4062    } else
4063      WriteBits32Unknown(Rt);
4064  }
4065  return true;
4066}
4067
4068// STM (Store Multiple Increment After) stores multiple registers to consecutive
4069// memory locations using an address
4070// from a base register.  The consecutive memory locations start at this
4071// address, and the address just above the last
4072// of those locations can optionally be written back to the base register.
4073bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
4074                                       const ARMEncoding encoding) {
4075#if 0
4076    if ConditionPassed() then
4077        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4078        address = R[n];
4079
4080        for i = 0 to 14
4081            if registers<i> == '1' then
4082                if i == n && wback && i != LowestSetBit(registers) then
4083                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4084                else
4085                    MemA[address,4] = R[i];
4086                address = address + 4;
4087
4088        if registers<15> == '1' then // Only possible for encoding A1
4089            MemA[address,4] = PCStoreValue();
4090        if wback then R[n] = R[n] + 4*BitCount(registers);
4091#endif
4092
4093  bool success = false;
4094
4095  if (ConditionPassed(opcode)) {
4096    uint32_t n;
4097    uint32_t registers = 0;
4098    bool wback;
4099    const uint32_t addr_byte_size = GetAddressByteSize();
4100
4101    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4102    switch (encoding) {
4103    case eEncodingT1:
4104      // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4105      n = Bits32(opcode, 10, 8);
4106      registers = Bits32(opcode, 7, 0);
4107      registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
4108      wback = true;
4109
4110      // if BitCount(registers) < 1 then UNPREDICTABLE;
4111      if (BitCount(registers) < 1)
4112        return false;
4113
4114      break;
4115
4116    case eEncodingT2:
4117      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4118      n = Bits32(opcode, 19, 16);
4119      registers = Bits32(opcode, 15, 0);
4120      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4121      wback = BitIsSet(opcode, 21);
4122
4123      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4124      if ((n == 15) || (BitCount(registers) < 2))
4125        return false;
4126
4127      // if wback && registers<n> == '1' then UNPREDICTABLE;
4128      if (wback && BitIsSet(registers, n))
4129        return false;
4130
4131      break;
4132
4133    case eEncodingA1:
4134      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4135      n = Bits32(opcode, 19, 16);
4136      registers = Bits32(opcode, 15, 0);
4137      wback = BitIsSet(opcode, 21);
4138
4139      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4140      if ((n == 15) || (BitCount(registers) < 1))
4141        return false;
4142
4143      break;
4144
4145    default:
4146      return false;
4147    }
4148
4149    // address = R[n];
4150    int32_t offset = 0;
4151    const addr_t address =
4152        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4153    if (!success)
4154      return false;
4155
4156    EmulateInstruction::Context context;
4157    context.type = EmulateInstruction::eContextRegisterStore;
4158    RegisterInfo base_reg;
4159    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4160
4161    // for i = 0 to 14
4162    uint32_t lowest_set_bit = 14;
4163    for (uint32_t i = 0; i < 14; ++i) {
4164      // if registers<i> == '1' then
4165      if (BitIsSet(registers, i)) {
4166        if (i < lowest_set_bit)
4167          lowest_set_bit = i;
4168        // if i == n && wback && i != LowestSetBit(registers) then
4169        if ((i == n) && wback && (i != lowest_set_bit))
4170          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
4171          // T1 and A1
4172          WriteBits32UnknownToMemory(address + offset);
4173        else {
4174          // MemA[address,4] = R[i];
4175          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4176                                               0, &success);
4177          if (!success)
4178            return false;
4179
4180          RegisterInfo data_reg;
4181          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4182          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4183          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4184            return false;
4185        }
4186
4187        // address = address + 4;
4188        offset += addr_byte_size;
4189      }
4190    }
4191
4192    // if registers<15> == '1' then // Only possible for encoding A1
4193    //     MemA[address,4] = PCStoreValue();
4194    if (BitIsSet(registers, 15)) {
4195      RegisterInfo pc_reg;
4196      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4197      context.SetRegisterPlusOffset(pc_reg, 8);
4198      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4199      if (!success)
4200        return false;
4201
4202      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4203        return false;
4204    }
4205
4206    // if wback then R[n] = R[n] + 4*BitCount(registers);
4207    if (wback) {
4208      offset = addr_byte_size * BitCount(registers);
4209      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4210      context.SetImmediateSigned(offset);
4211      addr_t data = address + offset;
4212      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4213                                 data))
4214        return false;
4215    }
4216  }
4217  return true;
4218}
4219
4220// STMDA (Store Multiple Decrement After) stores multiple registers to
4221// consecutive memory locations using an address
4222// from a base register.  The consecutive memory locations end at this address,
4223// and the address just below the lowest
4224// of those locations can optionally be written back to the base register.
4225bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
4226                                         const ARMEncoding encoding) {
4227#if 0
4228    if ConditionPassed() then
4229        EncodingSpecificOperations();
4230        address = R[n] - 4*BitCount(registers) + 4;
4231
4232        for i = 0 to 14
4233            if registers<i> == '1' then
4234                if i == n && wback && i != LowestSetBit(registers) then
4235                    MemA[address,4] = bits(32) UNKNOWN;
4236                else
4237                    MemA[address,4] = R[i];
4238                address = address + 4;
4239
4240        if registers<15> == '1' then
4241            MemA[address,4] = PCStoreValue();
4242
4243        if wback then R[n] = R[n] - 4*BitCount(registers);
4244#endif
4245
4246  bool success = false;
4247
4248  if (ConditionPassed(opcode)) {
4249    uint32_t n;
4250    uint32_t registers = 0;
4251    bool wback;
4252    const uint32_t addr_byte_size = GetAddressByteSize();
4253
4254    // EncodingSpecificOperations();
4255    switch (encoding) {
4256    case eEncodingA1:
4257      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4258      n = Bits32(opcode, 19, 16);
4259      registers = Bits32(opcode, 15, 0);
4260      wback = BitIsSet(opcode, 21);
4261
4262      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4263      if ((n == 15) || (BitCount(registers) < 1))
4264        return false;
4265      break;
4266    default:
4267      return false;
4268    }
4269
4270    // address = R[n] - 4*BitCount(registers) + 4;
4271    int32_t offset = 0;
4272    addr_t Rn = ReadCoreReg(n, &success);
4273    if (!success)
4274      return false;
4275
4276    addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
4277
4278    EmulateInstruction::Context context;
4279    context.type = EmulateInstruction::eContextRegisterStore;
4280    RegisterInfo base_reg;
4281    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4282
4283    // for i = 0 to 14
4284    uint32_t lowest_bit_set = 14;
4285    for (uint32_t i = 0; i < 14; ++i) {
4286      // if registers<i> == '1' then
4287      if (BitIsSet(registers, i)) {
4288        if (i < lowest_bit_set)
4289          lowest_bit_set = i;
4290        // if i == n && wback && i != LowestSetBit(registers) then
4291        if ((i == n) && wback && (i != lowest_bit_set))
4292          // MemA[address,4] = bits(32) UNKNOWN;
4293          WriteBits32UnknownToMemory(address + offset);
4294        else {
4295          // MemA[address,4] = R[i];
4296          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4297                                               0, &success);
4298          if (!success)
4299            return false;
4300
4301          RegisterInfo data_reg;
4302          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4303          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4304                                                  Rn - (address + offset));
4305          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4306            return false;
4307        }
4308
4309        // address = address + 4;
4310        offset += addr_byte_size;
4311      }
4312    }
4313
4314    // if registers<15> == '1' then
4315    //    MemA[address,4] = PCStoreValue();
4316    if (BitIsSet(registers, 15)) {
4317      RegisterInfo pc_reg;
4318      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4319      context.SetRegisterPlusOffset(pc_reg, 8);
4320      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4321      if (!success)
4322        return false;
4323
4324      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4325        return false;
4326    }
4327
4328    // if wback then R[n] = R[n] - 4*BitCount(registers);
4329    if (wback) {
4330      offset = (addr_byte_size * BitCount(registers)) * -1;
4331      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4332      context.SetImmediateSigned(offset);
4333      addr_t data = Rn + offset;
4334      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4335                                 data))
4336        return false;
4337    }
4338  }
4339  return true;
4340}
4341
4342// STMDB (Store Multiple Decrement Before) stores multiple registers to
4343// consecutive memory locations using an address
4344// from a base register.  The consecutive memory locations end just below this
4345// address, and the address of the first of
4346// those locations can optionally be written back to the base register.
4347bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
4348                                         const ARMEncoding encoding) {
4349#if 0
4350    if ConditionPassed() then
4351        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4352        address = R[n] - 4*BitCount(registers);
4353
4354        for i = 0 to 14
4355            if registers<i> == '1' then
4356                if i == n && wback && i != LowestSetBit(registers) then
4357                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4358                else
4359                    MemA[address,4] = R[i];
4360                address = address + 4;
4361
4362        if registers<15> == '1' then // Only possible for encoding A1
4363            MemA[address,4] = PCStoreValue();
4364
4365        if wback then R[n] = R[n] - 4*BitCount(registers);
4366#endif
4367
4368  bool success = false;
4369
4370  if (ConditionPassed(opcode)) {
4371    uint32_t n;
4372    uint32_t registers = 0;
4373    bool wback;
4374    const uint32_t addr_byte_size = GetAddressByteSize();
4375
4376    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4377    switch (encoding) {
4378    case eEncodingT1:
4379      // if W == '1' && Rn == '1101' then SEE PUSH;
4380      if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
4381        // See PUSH
4382      }
4383      // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4384      n = Bits32(opcode, 19, 16);
4385      registers = Bits32(opcode, 15, 0);
4386      registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4387      wback = BitIsSet(opcode, 21);
4388      // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4389      if ((n == 15) || BitCount(registers) < 2)
4390        return false;
4391      // if wback && registers<n> == '1' then UNPREDICTABLE;
4392      if (wback && BitIsSet(registers, n))
4393        return false;
4394      break;
4395
4396    case eEncodingA1:
4397      // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
4398      // PUSH;
4399      if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
4400          BitCount(Bits32(opcode, 15, 0)) >= 2) {
4401        // See Push
4402      }
4403      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4404      n = Bits32(opcode, 19, 16);
4405      registers = Bits32(opcode, 15, 0);
4406      wback = BitIsSet(opcode, 21);
4407      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4408      if ((n == 15) || BitCount(registers) < 1)
4409        return false;
4410      break;
4411
4412    default:
4413      return false;
4414    }
4415
4416    // address = R[n] - 4*BitCount(registers);
4417
4418    int32_t offset = 0;
4419    addr_t Rn =
4420        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4421    if (!success)
4422      return false;
4423
4424    addr_t address = Rn - (addr_byte_size * BitCount(registers));
4425
4426    EmulateInstruction::Context context;
4427    context.type = EmulateInstruction::eContextRegisterStore;
4428    RegisterInfo base_reg;
4429    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4430
4431    // for i = 0 to 14
4432    uint32_t lowest_set_bit = 14;
4433    for (uint32_t i = 0; i < 14; ++i) {
4434      // if registers<i> == '1' then
4435      if (BitIsSet(registers, i)) {
4436        if (i < lowest_set_bit)
4437          lowest_set_bit = i;
4438        // if i == n && wback && i != LowestSetBit(registers) then
4439        if ((i == n) && wback && (i != lowest_set_bit))
4440          // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
4441          // A1
4442          WriteBits32UnknownToMemory(address + offset);
4443        else {
4444          // MemA[address,4] = R[i];
4445          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4446                                               0, &success);
4447          if (!success)
4448            return false;
4449
4450          RegisterInfo data_reg;
4451          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4452          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4453                                                  Rn - (address + offset));
4454          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4455            return false;
4456        }
4457
4458        // address = address + 4;
4459        offset += addr_byte_size;
4460      }
4461    }
4462
4463    // if registers<15> == '1' then // Only possible for encoding A1
4464    //     MemA[address,4] = PCStoreValue();
4465    if (BitIsSet(registers, 15)) {
4466      RegisterInfo pc_reg;
4467      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4468      context.SetRegisterPlusOffset(pc_reg, 8);
4469      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4470      if (!success)
4471        return false;
4472
4473      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4474        return false;
4475    }
4476
4477    // if wback then R[n] = R[n] - 4*BitCount(registers);
4478    if (wback) {
4479      offset = (addr_byte_size * BitCount(registers)) * -1;
4480      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4481      context.SetImmediateSigned(offset);
4482      addr_t data = Rn + offset;
4483      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4484                                 data))
4485        return false;
4486    }
4487  }
4488  return true;
4489}
4490
4491// STMIB (Store Multiple Increment Before) stores multiple registers to
4492// consecutive memory locations using an address
4493// from a base register.  The consecutive memory locations start just above this
4494// address, and the address of the last
4495// of those locations can optionally be written back to the base register.
4496bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
4497                                         const ARMEncoding encoding) {
4498#if 0
4499    if ConditionPassed() then
4500        EncodingSpecificOperations();
4501        address = R[n] + 4;
4502
4503        for i = 0 to 14
4504            if registers<i> == '1' then
4505                if i == n && wback && i != LowestSetBit(registers) then
4506                    MemA[address,4] = bits(32) UNKNOWN;
4507                else
4508                    MemA[address,4] = R[i];
4509                address = address + 4;
4510
4511        if registers<15> == '1' then
4512            MemA[address,4] = PCStoreValue();
4513
4514        if wback then R[n] = R[n] + 4*BitCount(registers);
4515#endif
4516
4517  bool success = false;
4518
4519  if (ConditionPassed(opcode)) {
4520    uint32_t n;
4521    uint32_t registers = 0;
4522    bool wback;
4523    const uint32_t addr_byte_size = GetAddressByteSize();
4524
4525    // EncodingSpecificOperations();
4526    switch (encoding) {
4527    case eEncodingA1:
4528      // n = UInt(Rn); registers = register_list; wback = (W == '1');
4529      n = Bits32(opcode, 19, 16);
4530      registers = Bits32(opcode, 15, 0);
4531      wback = BitIsSet(opcode, 21);
4532
4533      // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4534      if ((n == 15) && (BitCount(registers) < 1))
4535        return false;
4536      break;
4537    default:
4538      return false;
4539    }
4540    // address = R[n] + 4;
4541
4542    int32_t offset = 0;
4543    addr_t Rn = ReadCoreReg(n, &success);
4544    if (!success)
4545      return false;
4546
4547    addr_t address = Rn + addr_byte_size;
4548
4549    EmulateInstruction::Context context;
4550    context.type = EmulateInstruction::eContextRegisterStore;
4551    RegisterInfo base_reg;
4552    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4553
4554    uint32_t lowest_set_bit = 14;
4555    // for i = 0 to 14
4556    for (uint32_t i = 0; i < 14; ++i) {
4557      // if registers<i> == '1' then
4558      if (BitIsSet(registers, i)) {
4559        if (i < lowest_set_bit)
4560          lowest_set_bit = i;
4561        // if i == n && wback && i != LowestSetBit(registers) then
4562        if ((i == n) && wback && (i != lowest_set_bit))
4563          // MemA[address,4] = bits(32) UNKNOWN;
4564          WriteBits32UnknownToMemory(address + offset);
4565        // else
4566        else {
4567          // MemA[address,4] = R[i];
4568          uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
4569                                               0, &success);
4570          if (!success)
4571            return false;
4572
4573          RegisterInfo data_reg;
4574          GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4575          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4576                                                  offset + addr_byte_size);
4577          if (!MemAWrite(context, address + offset, data, addr_byte_size))
4578            return false;
4579        }
4580
4581        // address = address + 4;
4582        offset += addr_byte_size;
4583      }
4584    }
4585
4586    // if registers<15> == '1' then
4587    // MemA[address,4] = PCStoreValue();
4588    if (BitIsSet(registers, 15)) {
4589      RegisterInfo pc_reg;
4590      GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
4591      context.SetRegisterPlusOffset(pc_reg, 8);
4592      const uint32_t pc = ReadCoreReg(PC_REG, &success);
4593      if (!success)
4594        return false;
4595
4596      if (!MemAWrite(context, address + offset, pc, addr_byte_size))
4597        return false;
4598    }
4599
4600    // if wback then R[n] = R[n] + 4*BitCount(registers);
4601    if (wback) {
4602      offset = addr_byte_size * BitCount(registers);
4603      context.type = EmulateInstruction::eContextAdjustBaseRegister;
4604      context.SetImmediateSigned(offset);
4605      addr_t data = Rn + offset;
4606      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4607                                 data))
4608        return false;
4609    }
4610  }
4611  return true;
4612}
4613
4614// STR (store immediate) calculates an address from a base register value and an
4615// immediate offset, and stores a word
4616// from a register to memory.  It can use offset, post-indexed, or pre-indexed
4617// addressing.
4618bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
4619                                            const ARMEncoding encoding) {
4620#if 0
4621    if ConditionPassed() then
4622        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4623        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4624        address = if index then offset_addr else R[n];
4625        if UnalignedSupport() || address<1:0> == '00' then
4626            MemU[address,4] = R[t];
4627        else // Can only occur before ARMv7
4628            MemU[address,4] = bits(32) UNKNOWN;
4629        if wback then R[n] = offset_addr;
4630#endif
4631
4632  bool success = false;
4633
4634  if (ConditionPassed(opcode)) {
4635    const uint32_t addr_byte_size = GetAddressByteSize();
4636
4637    uint32_t t;
4638    uint32_t n;
4639    uint32_t imm32;
4640    bool index;
4641    bool add;
4642    bool wback;
4643    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4644    switch (encoding) {
4645    case eEncodingT1:
4646      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4647      t = Bits32(opcode, 2, 0);
4648      n = Bits32(opcode, 5, 3);
4649      imm32 = Bits32(opcode, 10, 6) << 2;
4650
4651      // index = TRUE; add = TRUE; wback = FALSE;
4652      index = true;
4653      add = false;
4654      wback = false;
4655      break;
4656
4657    case eEncodingT2:
4658      // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4659      t = Bits32(opcode, 10, 8);
4660      n = 13;
4661      imm32 = Bits32(opcode, 7, 0) << 2;
4662
4663      // index = TRUE; add = TRUE; wback = FALSE;
4664      index = true;
4665      add = true;
4666      wback = false;
4667      break;
4668
4669    case eEncodingT3:
4670      // if Rn == '1111' then UNDEFINED;
4671      if (Bits32(opcode, 19, 16) == 15)
4672        return false;
4673
4674      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4675      t = Bits32(opcode, 15, 12);
4676      n = Bits32(opcode, 19, 16);
4677      imm32 = Bits32(opcode, 11, 0);
4678
4679      // index = TRUE; add = TRUE; wback = FALSE;
4680      index = true;
4681      add = true;
4682      wback = false;
4683
4684      // if t == 15 then UNPREDICTABLE;
4685      if (t == 15)
4686        return false;
4687      break;
4688
4689    case eEncodingT4:
4690      // if P == '1' && U == '1' && W == '0' then SEE STRT;
4691      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
4692      // '00000100' then SEE PUSH;
4693      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4694      if ((Bits32(opcode, 19, 16) == 15) ||
4695          (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
4696        return false;
4697
4698      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4699      t = Bits32(opcode, 15, 12);
4700      n = Bits32(opcode, 19, 16);
4701      imm32 = Bits32(opcode, 7, 0);
4702
4703      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4704      index = BitIsSet(opcode, 10);
4705      add = BitIsSet(opcode, 9);
4706      wback = BitIsSet(opcode, 8);
4707
4708      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4709      if ((t == 15) || (wback && (n == t)))
4710        return false;
4711      break;
4712
4713    default:
4714      return false;
4715    }
4716
4717    addr_t offset_addr;
4718    addr_t address;
4719
4720    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4721    uint32_t base_address = ReadCoreReg(n, &success);
4722    if (!success)
4723      return false;
4724
4725    if (add)
4726      offset_addr = base_address + imm32;
4727    else
4728      offset_addr = base_address - imm32;
4729
4730    // address = if index then offset_addr else R[n];
4731    if (index)
4732      address = offset_addr;
4733    else
4734      address = base_address;
4735
4736    EmulateInstruction::Context context;
4737    if (n == 13)
4738      context.type = eContextPushRegisterOnStack;
4739    else
4740      context.type = eContextRegisterStore;
4741
4742    RegisterInfo base_reg;
4743    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4744
4745    // if UnalignedSupport() || address<1:0> == '00' then
4746    if (UnalignedSupport() ||
4747        (BitIsClear(address, 1) && BitIsClear(address, 0))) {
4748      // MemU[address,4] = R[t];
4749      uint32_t data =
4750          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4751      if (!success)
4752        return false;
4753
4754      RegisterInfo data_reg;
4755      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4756      int32_t offset = address - base_address;
4757      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
4758      if (!MemUWrite(context, address, data, addr_byte_size))
4759        return false;
4760    } else {
4761      // MemU[address,4] = bits(32) UNKNOWN;
4762      WriteBits32UnknownToMemory(address);
4763    }
4764
4765    // if wback then R[n] = offset_addr;
4766    if (wback) {
4767      if (n == 13)
4768        context.type = eContextAdjustStackPointer;
4769      else
4770        context.type = eContextAdjustBaseRegister;
4771      context.SetAddress(offset_addr);
4772
4773      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4774                                 offset_addr))
4775        return false;
4776    }
4777  }
4778  return true;
4779}
4780
4781// STR (Store Register) calculates an address from a base register value and an
4782// offset register value, stores a
4783// word from a register to memory.   The offset register value can optionally be
4784// shifted.
4785bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
4786                                               const ARMEncoding encoding) {
4787#if 0
4788    if ConditionPassed() then
4789        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4790        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4791        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4792        address = if index then offset_addr else R[n];
4793        if t == 15 then // Only possible for encoding A1
4794            data = PCStoreValue();
4795        else
4796            data = R[t];
4797        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4798            MemU[address,4] = data;
4799        else // Can only occur before ARMv7
4800            MemU[address,4] = bits(32) UNKNOWN;
4801        if wback then R[n] = offset_addr;
4802#endif
4803
4804  bool success = false;
4805
4806  if (ConditionPassed(opcode)) {
4807    const uint32_t addr_byte_size = GetAddressByteSize();
4808
4809    uint32_t t;
4810    uint32_t n;
4811    uint32_t m;
4812    ARM_ShifterType shift_t;
4813    uint32_t shift_n;
4814    bool index;
4815    bool add;
4816    bool wback;
4817
4818    // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4819    switch (encoding) {
4820    case eEncodingT1:
4821      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
4822      // in ThumbEE";
4823      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4824      t = Bits32(opcode, 2, 0);
4825      n = Bits32(opcode, 5, 3);
4826      m = Bits32(opcode, 8, 6);
4827
4828      // index = TRUE; add = TRUE; wback = FALSE;
4829      index = true;
4830      add = true;
4831      wback = false;
4832
4833      // (shift_t, shift_n) = (SRType_LSL, 0);
4834      shift_t = SRType_LSL;
4835      shift_n = 0;
4836      break;
4837
4838    case eEncodingT2:
4839      // if Rn == '1111' then UNDEFINED;
4840      if (Bits32(opcode, 19, 16) == 15)
4841        return false;
4842
4843      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4844      t = Bits32(opcode, 15, 12);
4845      n = Bits32(opcode, 19, 16);
4846      m = Bits32(opcode, 3, 0);
4847
4848      // index = TRUE; add = TRUE; wback = FALSE;
4849      index = true;
4850      add = true;
4851      wback = false;
4852
4853      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4854      shift_t = SRType_LSL;
4855      shift_n = Bits32(opcode, 5, 4);
4856
4857      // if t == 15 || BadReg(m) then UNPREDICTABLE;
4858      if ((t == 15) || (BadReg(m)))
4859        return false;
4860      break;
4861
4862    case eEncodingA1: {
4863      // if P == '0' && W == '1' then SEE STRT;
4864      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4865      t = Bits32(opcode, 15, 12);
4866      n = Bits32(opcode, 19, 16);
4867      m = Bits32(opcode, 3, 0);
4868
4869      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
4870      // (W == '1');
4871      index = BitIsSet(opcode, 24);
4872      add = BitIsSet(opcode, 23);
4873      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
4874
4875      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4876      uint32_t typ = Bits32(opcode, 6, 5);
4877      uint32_t imm5 = Bits32(opcode, 11, 7);
4878      shift_n = DecodeImmShift(typ, imm5, shift_t);
4879
4880      // if m == 15 then UNPREDICTABLE;
4881      if (m == 15)
4882        return false;
4883
4884      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4885      if (wback && ((n == 15) || (n == t)))
4886        return false;
4887
4888      break;
4889    }
4890    default:
4891      return false;
4892    }
4893
4894    addr_t offset_addr;
4895    addr_t address;
4896    int32_t offset = 0;
4897
4898    addr_t base_address =
4899        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4900    if (!success)
4901      return false;
4902
4903    uint32_t Rm_data =
4904        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4905    if (!success)
4906      return false;
4907
4908    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4909    offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
4910    if (!success)
4911      return false;
4912
4913    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4914    if (add)
4915      offset_addr = base_address + offset;
4916    else
4917      offset_addr = base_address - offset;
4918
4919    // address = if index then offset_addr else R[n];
4920    if (index)
4921      address = offset_addr;
4922    else
4923      address = base_address;
4924
4925    uint32_t data;
4926    // if t == 15 then // Only possible for encoding A1
4927    if (t == 15)
4928      // data = PCStoreValue();
4929      data = ReadCoreReg(PC_REG, &success);
4930    else
4931      // data = R[t];
4932      data =
4933          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4934
4935    if (!success)
4936      return false;
4937
4938    EmulateInstruction::Context context;
4939    context.type = eContextRegisterStore;
4940
4941    // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
4942    // InstrSet_ARM then
4943    if (UnalignedSupport() ||
4944        (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
4945        CurrentInstrSet() == eModeARM) {
4946      // MemU[address,4] = data;
4947
4948      RegisterInfo base_reg;
4949      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4950
4951      RegisterInfo data_reg;
4952      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4953
4954      context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
4955                                              address - base_address);
4956      if (!MemUWrite(context, address, data, addr_byte_size))
4957        return false;
4958
4959    } else
4960      // MemU[address,4] = bits(32) UNKNOWN;
4961      WriteBits32UnknownToMemory(address);
4962
4963    // if wback then R[n] = offset_addr;
4964    if (wback) {
4965      context.type = eContextRegisterLoad;
4966      context.SetAddress(offset_addr);
4967      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
4968                                 offset_addr))
4969        return false;
4970    }
4971  }
4972  return true;
4973}
4974
4975bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
4976                                             const ARMEncoding encoding) {
4977#if 0
4978    if ConditionPassed() then
4979        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4980        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4981        address = if index then offset_addr else R[n];
4982        MemU[address,1] = R[t]<7:0>;
4983        if wback then R[n] = offset_addr;
4984#endif
4985
4986  bool success = false;
4987
4988  if (ConditionPassed(opcode)) {
4989    uint32_t t;
4990    uint32_t n;
4991    uint32_t imm32;
4992    bool index;
4993    bool add;
4994    bool wback;
4995    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4996    switch (encoding) {
4997    case eEncodingT1:
4998      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4999      t = Bits32(opcode, 2, 0);
5000      n = Bits32(opcode, 5, 3);
5001      imm32 = Bits32(opcode, 10, 6);
5002
5003      // index = TRUE; add = TRUE; wback = FALSE;
5004      index = true;
5005      add = true;
5006      wback = false;
5007      break;
5008
5009    case eEncodingT2:
5010      // if Rn == '1111' then UNDEFINED;
5011      if (Bits32(opcode, 19, 16) == 15)
5012        return false;
5013
5014      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5015      t = Bits32(opcode, 15, 12);
5016      n = Bits32(opcode, 19, 16);
5017      imm32 = Bits32(opcode, 11, 0);
5018
5019      // index = TRUE; add = TRUE; wback = FALSE;
5020      index = true;
5021      add = true;
5022      wback = false;
5023
5024      // if BadReg(t) then UNPREDICTABLE;
5025      if (BadReg(t))
5026        return false;
5027      break;
5028
5029    case eEncodingT3:
5030      // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5031      // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5032      if (Bits32(opcode, 19, 16) == 15)
5033        return false;
5034
5035      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5036      t = Bits32(opcode, 15, 12);
5037      n = Bits32(opcode, 19, 16);
5038      imm32 = Bits32(opcode, 7, 0);
5039
5040      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5041      index = BitIsSet(opcode, 10);
5042      add = BitIsSet(opcode, 9);
5043      wback = BitIsSet(opcode, 8);
5044
5045      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5046      if ((BadReg(t)) || (wback && (n == t)))
5047        return false;
5048      break;
5049
5050    default:
5051      return false;
5052    }
5053
5054    addr_t offset_addr;
5055    addr_t address;
5056    addr_t base_address =
5057        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5058    if (!success)
5059      return false;
5060
5061    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5062    if (add)
5063      offset_addr = base_address + imm32;
5064    else
5065      offset_addr = base_address - imm32;
5066
5067    // address = if index then offset_addr else R[n];
5068    if (index)
5069      address = offset_addr;
5070    else
5071      address = base_address;
5072
5073    // MemU[address,1] = R[t]<7:0>
5074    RegisterInfo base_reg;
5075    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5076
5077    RegisterInfo data_reg;
5078    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5079
5080    EmulateInstruction::Context context;
5081    context.type = eContextRegisterStore;
5082    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
5083                                            address - base_address);
5084
5085    uint32_t data =
5086        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5087    if (!success)
5088      return false;
5089
5090    data = Bits32(data, 7, 0);
5091
5092    if (!MemUWrite(context, address, data, 1))
5093      return false;
5094
5095    // if wback then R[n] = offset_addr;
5096    if (wback) {
5097      context.type = eContextRegisterLoad;
5098      context.SetAddress(offset_addr);
5099      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5100                                 offset_addr))
5101        return false;
5102    }
5103  }
5104
5105  return true;
5106}
5107
5108// STRH (register) calculates an address from a base register value and an
5109// offset register value, and stores a
5110// halfword from a register to memory.  The offset register value can be shifted
5111// left by 0, 1, 2, or 3 bits.
5112bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
5113                                                const ARMEncoding encoding) {
5114#if 0
5115    if ConditionPassed() then
5116        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5117        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5118        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5119        address = if index then offset_addr else R[n];
5120        if UnalignedSupport() || address<0> == '0' then
5121            MemU[address,2] = R[t]<15:0>;
5122        else // Can only occur before ARMv7
5123            MemU[address,2] = bits(16) UNKNOWN;
5124        if wback then R[n] = offset_addr;
5125#endif
5126
5127  bool success = false;
5128
5129  if (ConditionPassed(opcode)) {
5130    uint32_t t;
5131    uint32_t n;
5132    uint32_t m;
5133    bool index;
5134    bool add;
5135    bool wback;
5136    ARM_ShifterType shift_t;
5137    uint32_t shift_n;
5138
5139    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5140    switch (encoding) {
5141    case eEncodingT1:
5142      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
5143      // in ThumbEE";
5144      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5145      t = Bits32(opcode, 2, 0);
5146      n = Bits32(opcode, 5, 3);
5147      m = Bits32(opcode, 8, 6);
5148
5149      // index = TRUE; add = TRUE; wback = FALSE;
5150      index = true;
5151      add = true;
5152      wback = false;
5153
5154      // (shift_t, shift_n) = (SRType_LSL, 0);
5155      shift_t = SRType_LSL;
5156      shift_n = 0;
5157
5158      break;
5159
5160    case eEncodingT2:
5161      // if Rn == '1111' then UNDEFINED;
5162      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5163      t = Bits32(opcode, 15, 12);
5164      n = Bits32(opcode, 19, 16);
5165      m = Bits32(opcode, 3, 0);
5166      if (n == 15)
5167        return false;
5168
5169      // index = TRUE; add = TRUE; wback = FALSE;
5170      index = true;
5171      add = true;
5172      wback = false;
5173
5174      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5175      shift_t = SRType_LSL;
5176      shift_n = Bits32(opcode, 5, 4);
5177
5178      // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5179      if (BadReg(t) || BadReg(m))
5180        return false;
5181
5182      break;
5183
5184    case eEncodingA1:
5185      // if P == '0' && W == '1' then SEE STRHT;
5186      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5187      t = Bits32(opcode, 15, 12);
5188      n = Bits32(opcode, 19, 16);
5189      m = Bits32(opcode, 3, 0);
5190
5191      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
5192      // (W == '1');
5193      index = BitIsSet(opcode, 24);
5194      add = BitIsSet(opcode, 23);
5195      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5196
5197      // (shift_t, shift_n) = (SRType_LSL, 0);
5198      shift_t = SRType_LSL;
5199      shift_n = 0;
5200
5201      // if t == 15 || m == 15 then UNPREDICTABLE;
5202      if ((t == 15) || (m == 15))
5203        return false;
5204
5205      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5206      if (wback && ((n == 15) || (n == t)))
5207        return false;
5208
5209      break;
5210
5211    default:
5212      return false;
5213    }
5214
5215    uint32_t Rm = ReadCoreReg(m, &success);
5216    if (!success)
5217      return false;
5218
5219    uint32_t Rn = ReadCoreReg(n, &success);
5220    if (!success)
5221      return false;
5222
5223    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5224    uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
5225    if (!success)
5226      return false;
5227
5228    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5229    addr_t offset_addr;
5230    if (add)
5231      offset_addr = Rn + offset;
5232    else
5233      offset_addr = Rn - offset;
5234
5235    // address = if index then offset_addr else R[n];
5236    addr_t address;
5237    if (index)
5238      address = offset_addr;
5239    else
5240      address = Rn;
5241
5242    EmulateInstruction::Context context;
5243    context.type = eContextRegisterStore;
5244    RegisterInfo base_reg;
5245    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5246    RegisterInfo offset_reg;
5247    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5248
5249    // if UnalignedSupport() || address<0> == '0' then
5250    if (UnalignedSupport() || BitIsClear(address, 0)) {
5251      // MemU[address,2] = R[t]<15:0>;
5252      uint32_t Rt = ReadCoreReg(t, &success);
5253      if (!success)
5254        return false;
5255
5256      EmulateInstruction::Context context;
5257      context.type = eContextRegisterStore;
5258      RegisterInfo base_reg;
5259      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5260      RegisterInfo offset_reg;
5261      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5262      RegisterInfo data_reg;
5263      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5264      context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
5265                                                      data_reg);
5266
5267      if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
5268        return false;
5269    } else // Can only occur before ARMv7
5270    {
5271      // MemU[address,2] = bits(16) UNKNOWN;
5272    }
5273
5274    // if wback then R[n] = offset_addr;
5275    if (wback) {
5276      context.type = eContextAdjustBaseRegister;
5277      context.SetAddress(offset_addr);
5278      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5279                                 offset_addr))
5280        return false;
5281    }
5282  }
5283
5284  return true;
5285}
5286
5287// Add with Carry (immediate) adds an immediate value and the carry flag value
5288// to a register value,
5289// and writes the result to the destination register.  It can optionally update
5290// the condition flags
5291// based on the result.
5292bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
5293                                          const ARMEncoding encoding) {
5294#if 0
5295    // ARM pseudo code...
5296    if ConditionPassed() then
5297        EncodingSpecificOperations();
5298        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5299        if d == 15 then         // Can only occur for ARM encoding
5300            ALUWritePC(result); // setflags is always FALSE here
5301        else
5302            R[d] = result;
5303            if setflags then
5304                APSR.N = result<31>;
5305                APSR.Z = IsZeroBit(result);
5306                APSR.C = carry;
5307                APSR.V = overflow;
5308#endif
5309
5310  bool success = false;
5311
5312  if (ConditionPassed(opcode)) {
5313    uint32_t Rd, Rn;
5314    uint32_t
5315        imm32; // the immediate value to be added to the value obtained from Rn
5316    bool setflags;
5317    switch (encoding) {
5318    case eEncodingT1:
5319      Rd = Bits32(opcode, 11, 8);
5320      Rn = Bits32(opcode, 19, 16);
5321      setflags = BitIsSet(opcode, 20);
5322      imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5323      if (BadReg(Rd) || BadReg(Rn))
5324        return false;
5325      break;
5326    case eEncodingA1:
5327      Rd = Bits32(opcode, 15, 12);
5328      Rn = Bits32(opcode, 19, 16);
5329      setflags = BitIsSet(opcode, 20);
5330      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5331
5332      if (Rd == 15 && setflags)
5333        return EmulateSUBSPcLrEtc(opcode, encoding);
5334      break;
5335    default:
5336      return false;
5337    }
5338
5339    // Read the first operand.
5340    int32_t val1 = ReadCoreReg(Rn, &success);
5341    if (!success)
5342      return false;
5343
5344    AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5345
5346    EmulateInstruction::Context context;
5347    context.type = EmulateInstruction::eContextImmediate;
5348    context.SetNoArgs();
5349
5350    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5351                                   res.carry_out, res.overflow))
5352      return false;
5353  }
5354  return true;
5355}
5356
5357// Add with Carry (register) adds a register value, the carry flag value, and an
5358// optionally-shifted
5359// register value, and writes the result to the destination register.  It can
5360// optionally update the
5361// condition flags based on the result.
5362bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
5363                                          const ARMEncoding encoding) {
5364#if 0
5365    // ARM pseudo code...
5366    if ConditionPassed() then
5367        EncodingSpecificOperations();
5368        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5369        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5370        if d == 15 then         // Can only occur for ARM encoding
5371            ALUWritePC(result); // setflags is always FALSE here
5372        else
5373            R[d] = result;
5374            if setflags then
5375                APSR.N = result<31>;
5376                APSR.Z = IsZeroBit(result);
5377                APSR.C = carry;
5378                APSR.V = overflow;
5379#endif
5380
5381  bool success = false;
5382
5383  if (ConditionPassed(opcode)) {
5384    uint32_t Rd, Rn, Rm;
5385    ARM_ShifterType shift_t;
5386    uint32_t shift_n; // the shift applied to the value read from Rm
5387    bool setflags;
5388    switch (encoding) {
5389    case eEncodingT1:
5390      Rd = Rn = Bits32(opcode, 2, 0);
5391      Rm = Bits32(opcode, 5, 3);
5392      setflags = !InITBlock();
5393      shift_t = SRType_LSL;
5394      shift_n = 0;
5395      break;
5396    case eEncodingT2:
5397      Rd = Bits32(opcode, 11, 8);
5398      Rn = Bits32(opcode, 19, 16);
5399      Rm = Bits32(opcode, 3, 0);
5400      setflags = BitIsSet(opcode, 20);
5401      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5402      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5403        return false;
5404      break;
5405    case eEncodingA1:
5406      Rd = Bits32(opcode, 15, 12);
5407      Rn = Bits32(opcode, 19, 16);
5408      Rm = Bits32(opcode, 3, 0);
5409      setflags = BitIsSet(opcode, 20);
5410      shift_n = DecodeImmShiftARM(opcode, shift_t);
5411
5412      if (Rd == 15 && setflags)
5413        return EmulateSUBSPcLrEtc(opcode, encoding);
5414      break;
5415    default:
5416      return false;
5417    }
5418
5419    // Read the first operand.
5420    int32_t val1 = ReadCoreReg(Rn, &success);
5421    if (!success)
5422      return false;
5423
5424    // Read the second operand.
5425    int32_t val2 = ReadCoreReg(Rm, &success);
5426    if (!success)
5427      return false;
5428
5429    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5430    if (!success)
5431      return false;
5432    AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5433
5434    EmulateInstruction::Context context;
5435    context.type = EmulateInstruction::eContextImmediate;
5436    context.SetNoArgs();
5437
5438    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
5439                                   res.carry_out, res.overflow))
5440      return false;
5441  }
5442  return true;
5443}
5444
5445// This instruction adds an immediate value to the PC value to form a
5446// PC-relative address,
5447// and writes the result to the destination register.
5448bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
5449                                       const ARMEncoding encoding) {
5450#if 0
5451    // ARM pseudo code...
5452    if ConditionPassed() then
5453        EncodingSpecificOperations();
5454        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5455        if d == 15 then         // Can only occur for ARM encodings
5456            ALUWritePC(result);
5457        else
5458            R[d] = result;
5459#endif
5460
5461  bool success = false;
5462
5463  if (ConditionPassed(opcode)) {
5464    uint32_t Rd;
5465    uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5466    bool add;
5467    switch (encoding) {
5468    case eEncodingT1:
5469      Rd = Bits32(opcode, 10, 8);
5470      imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5471      add = true;
5472      break;
5473    case eEncodingT2:
5474    case eEncodingT3:
5475      Rd = Bits32(opcode, 11, 8);
5476      imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5477      add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5478      if (BadReg(Rd))
5479        return false;
5480      break;
5481    case eEncodingA1:
5482    case eEncodingA2:
5483      Rd = Bits32(opcode, 15, 12);
5484      imm32 = ARMExpandImm(opcode);          // imm32 = ARMExpandImm(imm12)
5485      add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5486      break;
5487    default:
5488      return false;
5489    }
5490
5491    // Read the PC value.
5492    uint32_t pc = ReadCoreReg(PC_REG, &success);
5493    if (!success)
5494      return false;
5495
5496    uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5497
5498    EmulateInstruction::Context context;
5499    context.type = EmulateInstruction::eContextImmediate;
5500    context.SetNoArgs();
5501
5502    if (!WriteCoreReg(context, result, Rd))
5503      return false;
5504  }
5505  return true;
5506}
5507
5508// This instruction performs a bitwise AND of a register value and an immediate
5509// value, and writes the result
5510// to the destination register.  It can optionally update the condition flags
5511// based on the result.
5512bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
5513                                          const ARMEncoding encoding) {
5514#if 0
5515    // ARM pseudo code...
5516    if ConditionPassed() then
5517        EncodingSpecificOperations();
5518        result = R[n] AND imm32;
5519        if d == 15 then         // Can only occur for ARM encoding
5520            ALUWritePC(result); // setflags is always FALSE here
5521        else
5522            R[d] = result;
5523            if setflags then
5524                APSR.N = result<31>;
5525                APSR.Z = IsZeroBit(result);
5526                APSR.C = carry;
5527                // APSR.V unchanged
5528#endif
5529
5530  bool success = false;
5531
5532  if (ConditionPassed(opcode)) {
5533    uint32_t Rd, Rn;
5534    uint32_t
5535        imm32; // the immediate value to be ANDed to the value obtained from Rn
5536    bool setflags;
5537    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5538    switch (encoding) {
5539    case eEncodingT1:
5540      Rd = Bits32(opcode, 11, 8);
5541      Rn = Bits32(opcode, 19, 16);
5542      setflags = BitIsSet(opcode, 20);
5543      imm32 = ThumbExpandImm_C(
5544          opcode, APSR_C,
5545          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5546      // if Rd == '1111' && S == '1' then SEE TST (immediate);
5547      if (Rd == 15 && setflags)
5548        return EmulateTSTImm(opcode, eEncodingT1);
5549      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5550        return false;
5551      break;
5552    case eEncodingA1:
5553      Rd = Bits32(opcode, 15, 12);
5554      Rn = Bits32(opcode, 19, 16);
5555      setflags = BitIsSet(opcode, 20);
5556      imm32 =
5557          ARMExpandImm_C(opcode, APSR_C,
5558                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5559
5560      if (Rd == 15 && setflags)
5561        return EmulateSUBSPcLrEtc(opcode, encoding);
5562      break;
5563    default:
5564      return false;
5565    }
5566
5567    // Read the first operand.
5568    uint32_t val1 = ReadCoreReg(Rn, &success);
5569    if (!success)
5570      return false;
5571
5572    uint32_t result = val1 & imm32;
5573
5574    EmulateInstruction::Context context;
5575    context.type = EmulateInstruction::eContextImmediate;
5576    context.SetNoArgs();
5577
5578    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5579      return false;
5580  }
5581  return true;
5582}
5583
5584// This instruction performs a bitwise AND of a register value and an
5585// optionally-shifted register value,
5586// and writes the result to the destination register.  It can optionally update
5587// the condition flags
5588// based on the result.
5589bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
5590                                          const ARMEncoding encoding) {
5591#if 0
5592    // ARM pseudo code...
5593    if ConditionPassed() then
5594        EncodingSpecificOperations();
5595        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5596        result = R[n] AND shifted;
5597        if d == 15 then         // Can only occur for ARM encoding
5598            ALUWritePC(result); // setflags is always FALSE here
5599        else
5600            R[d] = result;
5601            if setflags then
5602                APSR.N = result<31>;
5603                APSR.Z = IsZeroBit(result);
5604                APSR.C = carry;
5605                // APSR.V unchanged
5606#endif
5607
5608  bool success = false;
5609
5610  if (ConditionPassed(opcode)) {
5611    uint32_t Rd, Rn, Rm;
5612    ARM_ShifterType shift_t;
5613    uint32_t shift_n; // the shift applied to the value read from Rm
5614    bool setflags;
5615    uint32_t carry;
5616    switch (encoding) {
5617    case eEncodingT1:
5618      Rd = Rn = Bits32(opcode, 2, 0);
5619      Rm = Bits32(opcode, 5, 3);
5620      setflags = !InITBlock();
5621      shift_t = SRType_LSL;
5622      shift_n = 0;
5623      break;
5624    case eEncodingT2:
5625      Rd = Bits32(opcode, 11, 8);
5626      Rn = Bits32(opcode, 19, 16);
5627      Rm = Bits32(opcode, 3, 0);
5628      setflags = BitIsSet(opcode, 20);
5629      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5630      // if Rd == '1111' && S == '1' then SEE TST (register);
5631      if (Rd == 15 && setflags)
5632        return EmulateTSTReg(opcode, eEncodingT2);
5633      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5634        return false;
5635      break;
5636    case eEncodingA1:
5637      Rd = Bits32(opcode, 15, 12);
5638      Rn = Bits32(opcode, 19, 16);
5639      Rm = Bits32(opcode, 3, 0);
5640      setflags = BitIsSet(opcode, 20);
5641      shift_n = DecodeImmShiftARM(opcode, shift_t);
5642
5643      if (Rd == 15 && setflags)
5644        return EmulateSUBSPcLrEtc(opcode, encoding);
5645      break;
5646    default:
5647      return false;
5648    }
5649
5650    // Read the first operand.
5651    uint32_t val1 = ReadCoreReg(Rn, &success);
5652    if (!success)
5653      return false;
5654
5655    // Read the second operand.
5656    uint32_t val2 = ReadCoreReg(Rm, &success);
5657    if (!success)
5658      return false;
5659
5660    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5661    if (!success)
5662      return false;
5663    uint32_t result = val1 & shifted;
5664
5665    EmulateInstruction::Context context;
5666    context.type = EmulateInstruction::eContextImmediate;
5667    context.SetNoArgs();
5668
5669    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5670      return false;
5671  }
5672  return true;
5673}
5674
5675// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
5676// the complement of an
5677// immediate value, and writes the result to the destination register.  It can
5678// optionally update the
5679// condition flags based on the result.
5680bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
5681                                          const ARMEncoding encoding) {
5682#if 0
5683    // ARM pseudo code...
5684    if ConditionPassed() then
5685        EncodingSpecificOperations();
5686        result = R[n] AND NOT(imm32);
5687        if d == 15 then         // Can only occur for ARM encoding
5688            ALUWritePC(result); // setflags is always FALSE here
5689        else
5690            R[d] = result;
5691            if setflags then
5692                APSR.N = result<31>;
5693                APSR.Z = IsZeroBit(result);
5694                APSR.C = carry;
5695                // APSR.V unchanged
5696#endif
5697
5698  bool success = false;
5699
5700  if (ConditionPassed(opcode)) {
5701    uint32_t Rd, Rn;
5702    uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
5703                    // the value obtained from Rn
5704    bool setflags;
5705    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5706    switch (encoding) {
5707    case eEncodingT1:
5708      Rd = Bits32(opcode, 11, 8);
5709      Rn = Bits32(opcode, 19, 16);
5710      setflags = BitIsSet(opcode, 20);
5711      imm32 = ThumbExpandImm_C(
5712          opcode, APSR_C,
5713          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5714      if (BadReg(Rd) || BadReg(Rn))
5715        return false;
5716      break;
5717    case eEncodingA1:
5718      Rd = Bits32(opcode, 15, 12);
5719      Rn = Bits32(opcode, 19, 16);
5720      setflags = BitIsSet(opcode, 20);
5721      imm32 =
5722          ARMExpandImm_C(opcode, APSR_C,
5723                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5724
5725      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
5726      // instructions;
5727      if (Rd == 15 && setflags)
5728        return EmulateSUBSPcLrEtc(opcode, encoding);
5729      break;
5730    default:
5731      return false;
5732    }
5733
5734    // Read the first operand.
5735    uint32_t val1 = ReadCoreReg(Rn, &success);
5736    if (!success)
5737      return false;
5738
5739    uint32_t result = val1 & ~imm32;
5740
5741    EmulateInstruction::Context context;
5742    context.type = EmulateInstruction::eContextImmediate;
5743    context.SetNoArgs();
5744
5745    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5746      return false;
5747  }
5748  return true;
5749}
5750
5751// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
5752// the complement of an
5753// optionally-shifted register value, and writes the result to the destination
5754// register.
5755// It can optionally update the condition flags based on the result.
5756bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
5757                                          const ARMEncoding encoding) {
5758#if 0
5759    // ARM pseudo code...
5760    if ConditionPassed() then
5761        EncodingSpecificOperations();
5762        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5763        result = R[n] AND NOT(shifted);
5764        if d == 15 then         // Can only occur for ARM encoding
5765            ALUWritePC(result); // setflags is always FALSE here
5766        else
5767            R[d] = result;
5768            if setflags then
5769                APSR.N = result<31>;
5770                APSR.Z = IsZeroBit(result);
5771                APSR.C = carry;
5772                // APSR.V unchanged
5773#endif
5774
5775  bool success = false;
5776
5777  if (ConditionPassed(opcode)) {
5778    uint32_t Rd, Rn, Rm;
5779    ARM_ShifterType shift_t;
5780    uint32_t shift_n; // the shift applied to the value read from Rm
5781    bool setflags;
5782    uint32_t carry;
5783    switch (encoding) {
5784    case eEncodingT1:
5785      Rd = Rn = Bits32(opcode, 2, 0);
5786      Rm = Bits32(opcode, 5, 3);
5787      setflags = !InITBlock();
5788      shift_t = SRType_LSL;
5789      shift_n = 0;
5790      break;
5791    case eEncodingT2:
5792      Rd = Bits32(opcode, 11, 8);
5793      Rn = Bits32(opcode, 19, 16);
5794      Rm = Bits32(opcode, 3, 0);
5795      setflags = BitIsSet(opcode, 20);
5796      shift_n = DecodeImmShiftThumb(opcode, shift_t);
5797      if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5798        return false;
5799      break;
5800    case eEncodingA1:
5801      Rd = Bits32(opcode, 15, 12);
5802      Rn = Bits32(opcode, 19, 16);
5803      Rm = Bits32(opcode, 3, 0);
5804      setflags = BitIsSet(opcode, 20);
5805      shift_n = DecodeImmShiftARM(opcode, shift_t);
5806
5807      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
5808      // instructions;
5809      if (Rd == 15 && setflags)
5810        return EmulateSUBSPcLrEtc(opcode, encoding);
5811      break;
5812    default:
5813      return false;
5814    }
5815
5816    // Read the first operand.
5817    uint32_t val1 = ReadCoreReg(Rn, &success);
5818    if (!success)
5819      return false;
5820
5821    // Read the second operand.
5822    uint32_t val2 = ReadCoreReg(Rm, &success);
5823    if (!success)
5824      return false;
5825
5826    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5827    if (!success)
5828      return false;
5829    uint32_t result = val1 & ~shifted;
5830
5831    EmulateInstruction::Context context;
5832    context.type = EmulateInstruction::eContextImmediate;
5833    context.SetNoArgs();
5834
5835    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5836      return false;
5837  }
5838  return true;
5839}
5840
5841// LDR (immediate, ARM) calculates an address from a base register value and an
5842// immediate offset, loads a word
5843// from memory, and writes it to a register.  It can use offset, post-indexed,
5844// or pre-indexed addressing.
5845bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
5846                                                   const ARMEncoding encoding) {
5847#if 0
5848    if ConditionPassed() then
5849        EncodingSpecificOperations();
5850        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5851        address = if index then offset_addr else R[n];
5852        data = MemU[address,4];
5853        if wback then R[n] = offset_addr;
5854        if t == 15 then
5855            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5856        elsif UnalignedSupport() || address<1:0> = '00' then
5857            R[t] = data;
5858        else // Can only apply before ARMv7
5859            R[t] = ROR(data, 8*UInt(address<1:0>));
5860#endif
5861
5862  bool success = false;
5863
5864  if (ConditionPassed(opcode)) {
5865    const uint32_t addr_byte_size = GetAddressByteSize();
5866
5867    uint32_t t;
5868    uint32_t n;
5869    uint32_t imm32;
5870    bool index;
5871    bool add;
5872    bool wback;
5873
5874    switch (encoding) {
5875    case eEncodingA1:
5876      // if Rn == '1111' then SEE LDR (literal);
5877      // if P == '0' && W == '1' then SEE LDRT;
5878      // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
5879      // '000000000100' then SEE POP;
5880      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5881      t = Bits32(opcode, 15, 12);
5882      n = Bits32(opcode, 19, 16);
5883      imm32 = Bits32(opcode, 11, 0);
5884
5885      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
5886      // (W == '1');
5887      index = BitIsSet(opcode, 24);
5888      add = BitIsSet(opcode, 23);
5889      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
5890
5891      // if wback && n == t then UNPREDICTABLE;
5892      if (wback && (n == t))
5893        return false;
5894
5895      break;
5896
5897    default:
5898      return false;
5899    }
5900
5901    addr_t address;
5902    addr_t offset_addr;
5903    addr_t base_address = ReadCoreReg(n, &success);
5904    if (!success)
5905      return false;
5906
5907    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5908    if (add)
5909      offset_addr = base_address + imm32;
5910    else
5911      offset_addr = base_address - imm32;
5912
5913    // address = if index then offset_addr else R[n];
5914    if (index)
5915      address = offset_addr;
5916    else
5917      address = base_address;
5918
5919    // data = MemU[address,4];
5920
5921    RegisterInfo base_reg;
5922    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5923
5924    EmulateInstruction::Context context;
5925    context.type = eContextRegisterLoad;
5926    context.SetRegisterPlusOffset(base_reg, address - base_address);
5927
5928    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
5929    if (!success)
5930      return false;
5931
5932    // if wback then R[n] = offset_addr;
5933    if (wback) {
5934      context.type = eContextAdjustBaseRegister;
5935      context.SetAddress(offset_addr);
5936      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
5937                                 offset_addr))
5938        return false;
5939    }
5940
5941    // if t == 15 then
5942    if (t == 15) {
5943      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5944      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
5945        // LoadWritePC (data);
5946        context.type = eContextRegisterLoad;
5947        context.SetRegisterPlusOffset(base_reg, address - base_address);
5948        LoadWritePC(context, data);
5949      } else
5950        return false;
5951    }
5952    // elsif UnalignedSupport() || address<1:0> = '00' then
5953    else if (UnalignedSupport() ||
5954             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
5955      // R[t] = data;
5956      context.type = eContextRegisterLoad;
5957      context.SetRegisterPlusOffset(base_reg, address - base_address);
5958      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
5959                                 data))
5960        return false;
5961    }
5962    // else // Can only apply before ARMv7
5963    else {
5964      // R[t] = ROR(data, 8*UInt(address<1:0>));
5965      data = ROR(data, Bits32(address, 1, 0), &success);
5966      if (!success)
5967        return false;
5968      context.type = eContextRegisterLoad;
5969      context.SetImmediate(data);
5970      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
5971                                 data))
5972        return false;
5973    }
5974  }
5975  return true;
5976}
5977
5978// LDR (register) calculates an address from a base register value and an offset
5979// register value, loads a word
5980// from memory, and writes it to a register.  The offset register value can
5981// optionally be shifted.
5982bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
5983                                               const ARMEncoding encoding) {
5984#if 0
5985    if ConditionPassed() then
5986        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5987        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5988        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5989        address = if index then offset_addr else R[n];
5990        data = MemU[address,4];
5991        if wback then R[n] = offset_addr;
5992        if t == 15 then
5993            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5994        elsif UnalignedSupport() || address<1:0> = '00' then
5995            R[t] = data;
5996        else // Can only apply before ARMv7
5997            if CurrentInstrSet() == InstrSet_ARM then
5998                R[t] = ROR(data, 8*UInt(address<1:0>));
5999            else
6000                R[t] = bits(32) UNKNOWN;
6001#endif
6002
6003  bool success = false;
6004
6005  if (ConditionPassed(opcode)) {
6006    const uint32_t addr_byte_size = GetAddressByteSize();
6007
6008    uint32_t t;
6009    uint32_t n;
6010    uint32_t m;
6011    bool index;
6012    bool add;
6013    bool wback;
6014    ARM_ShifterType shift_t;
6015    uint32_t shift_n;
6016
6017    switch (encoding) {
6018    case eEncodingT1:
6019      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6020      // in ThumbEE";
6021      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6022      t = Bits32(opcode, 2, 0);
6023      n = Bits32(opcode, 5, 3);
6024      m = Bits32(opcode, 8, 6);
6025
6026      // index = TRUE; add = TRUE; wback = FALSE;
6027      index = true;
6028      add = true;
6029      wback = false;
6030
6031      // (shift_t, shift_n) = (SRType_LSL, 0);
6032      shift_t = SRType_LSL;
6033      shift_n = 0;
6034
6035      break;
6036
6037    case eEncodingT2:
6038      // if Rn == '1111' then SEE LDR (literal);
6039      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6040      t = Bits32(opcode, 15, 12);
6041      n = Bits32(opcode, 19, 16);
6042      m = Bits32(opcode, 3, 0);
6043
6044      // index = TRUE; add = TRUE; wback = FALSE;
6045      index = true;
6046      add = true;
6047      wback = false;
6048
6049      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6050      shift_t = SRType_LSL;
6051      shift_n = Bits32(opcode, 5, 4);
6052
6053      // if BadReg(m) then UNPREDICTABLE;
6054      if (BadReg(m))
6055        return false;
6056
6057      // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6058      if ((t == 15) && InITBlock() && !LastInITBlock())
6059        return false;
6060
6061      break;
6062
6063    case eEncodingA1: {
6064      // if P == '0' && W == '1' then SEE LDRT;
6065      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6066      t = Bits32(opcode, 15, 12);
6067      n = Bits32(opcode, 19, 16);
6068      m = Bits32(opcode, 3, 0);
6069
6070      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
6071      // (W == '1');
6072      index = BitIsSet(opcode, 24);
6073      add = BitIsSet(opcode, 23);
6074      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6075
6076      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6077      uint32_t type = Bits32(opcode, 6, 5);
6078      uint32_t imm5 = Bits32(opcode, 11, 7);
6079      shift_n = DecodeImmShift(type, imm5, shift_t);
6080
6081      // if m == 15 then UNPREDICTABLE;
6082      if (m == 15)
6083        return false;
6084
6085      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6086      if (wback && ((n == 15) || (n == t)))
6087        return false;
6088    } break;
6089
6090    default:
6091      return false;
6092    }
6093
6094    uint32_t Rm =
6095        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6096    if (!success)
6097      return false;
6098
6099    uint32_t Rn =
6100        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6101    if (!success)
6102      return false;
6103
6104    addr_t offset_addr;
6105    addr_t address;
6106
6107    // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an
6108    // application level alias for the CPSR".
6109    addr_t offset =
6110        Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
6111    if (!success)
6112      return false;
6113
6114    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6115    if (add)
6116      offset_addr = Rn + offset;
6117    else
6118      offset_addr = Rn - offset;
6119
6120    // address = if index then offset_addr else R[n];
6121    if (index)
6122      address = offset_addr;
6123    else
6124      address = Rn;
6125
6126    // data = MemU[address,4];
6127    RegisterInfo base_reg;
6128    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6129
6130    EmulateInstruction::Context context;
6131    context.type = eContextRegisterLoad;
6132    context.SetRegisterPlusOffset(base_reg, address - Rn);
6133
6134    uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
6135    if (!success)
6136      return false;
6137
6138    // if wback then R[n] = offset_addr;
6139    if (wback) {
6140      context.type = eContextAdjustBaseRegister;
6141      context.SetAddress(offset_addr);
6142      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6143                                 offset_addr))
6144        return false;
6145    }
6146
6147    // if t == 15 then
6148    if (t == 15) {
6149      // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6150      if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
6151        context.type = eContextRegisterLoad;
6152        context.SetRegisterPlusOffset(base_reg, address - Rn);
6153        LoadWritePC(context, data);
6154      } else
6155        return false;
6156    }
6157    // elsif UnalignedSupport() || address<1:0> = '00' then
6158    else if (UnalignedSupport() ||
6159             (BitIsClear(address, 1) && BitIsClear(address, 0))) {
6160      // R[t] = data;
6161      context.type = eContextRegisterLoad;
6162      context.SetRegisterPlusOffset(base_reg, address - Rn);
6163      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6164                                 data))
6165        return false;
6166    } else // Can only apply before ARMv7
6167    {
6168      // if CurrentInstrSet() == InstrSet_ARM then
6169      if (CurrentInstrSet() == eModeARM) {
6170        // R[t] = ROR(data, 8*UInt(address<1:0>));
6171        data = ROR(data, Bits32(address, 1, 0), &success);
6172        if (!success)
6173          return false;
6174        context.type = eContextRegisterLoad;
6175        context.SetImmediate(data);
6176        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6177                                   data))
6178          return false;
6179      } else {
6180        // R[t] = bits(32) UNKNOWN;
6181        WriteBits32Unknown(t);
6182      }
6183    }
6184  }
6185  return true;
6186}
6187
6188// LDRB (immediate, Thumb)
6189bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
6190                                                 const ARMEncoding encoding) {
6191#if 0
6192    if ConditionPassed() then
6193        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6194        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6195        address = if index then offset_addr else R[n];
6196        R[t] = ZeroExtend(MemU[address,1], 32);
6197        if wback then R[n] = offset_addr;
6198#endif
6199
6200  bool success = false;
6201
6202  if (ConditionPassed(opcode)) {
6203    uint32_t t;
6204    uint32_t n;
6205    uint32_t imm32;
6206    bool index;
6207    bool add;
6208    bool wback;
6209
6210    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6211    switch (encoding) {
6212    case eEncodingT1:
6213      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6214      t = Bits32(opcode, 2, 0);
6215      n = Bits32(opcode, 5, 3);
6216      imm32 = Bits32(opcode, 10, 6);
6217
6218      // index = TRUE; add = TRUE; wback = FALSE;
6219      index = true;
6220      add = true;
6221      wback = false;
6222
6223      break;
6224
6225    case eEncodingT2:
6226      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6227      t = Bits32(opcode, 15, 12);
6228      n = Bits32(opcode, 19, 16);
6229      imm32 = Bits32(opcode, 11, 0);
6230
6231      // index = TRUE; add = TRUE; wback = FALSE;
6232      index = true;
6233      add = true;
6234      wback = false;
6235
6236      // if Rt == '1111' then SEE PLD;
6237      if (t == 15)
6238        return false; // PLD is not implemented yet
6239
6240      // if Rn == '1111' then SEE LDRB (literal);
6241      if (n == 15)
6242        return EmulateLDRBLiteral(opcode, eEncodingT1);
6243
6244      // if t == 13 then UNPREDICTABLE;
6245      if (t == 13)
6246        return false;
6247
6248      break;
6249
6250    case eEncodingT3:
6251      // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6252      // if P == '0' && W == '0' then UNDEFINED;
6253      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6254        return false;
6255
6256      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6257      t = Bits32(opcode, 15, 12);
6258      n = Bits32(opcode, 19, 16);
6259      imm32 = Bits32(opcode, 7, 0);
6260
6261      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6262      index = BitIsSet(opcode, 10);
6263      add = BitIsSet(opcode, 9);
6264      wback = BitIsSet(opcode, 8);
6265
6266      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6267      if (t == 15)
6268        return false; // PLD is not implemented yet
6269
6270      // if Rn == '1111' then SEE LDRB (literal);
6271      if (n == 15)
6272        return EmulateLDRBLiteral(opcode, eEncodingT1);
6273
6274      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6275      if (BadReg(t) || (wback && (n == t)))
6276        return false;
6277
6278      break;
6279
6280    default:
6281      return false;
6282    }
6283
6284    uint32_t Rn =
6285        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6286    if (!success)
6287      return false;
6288
6289    addr_t address;
6290    addr_t offset_addr;
6291
6292    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6293    if (add)
6294      offset_addr = Rn + imm32;
6295    else
6296      offset_addr = Rn - imm32;
6297
6298    // address = if index then offset_addr else R[n];
6299    if (index)
6300      address = offset_addr;
6301    else
6302      address = Rn;
6303
6304    // R[t] = ZeroExtend(MemU[address,1], 32);
6305    RegisterInfo base_reg;
6306    RegisterInfo data_reg;
6307    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6308    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6309
6310    EmulateInstruction::Context context;
6311    context.type = eContextRegisterLoad;
6312    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
6313
6314    uint64_t data = MemURead(context, address, 1, 0, &success);
6315    if (!success)
6316      return false;
6317
6318    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6319      return false;
6320
6321    // if wback then R[n] = offset_addr;
6322    if (wback) {
6323      context.type = eContextAdjustBaseRegister;
6324      context.SetAddress(offset_addr);
6325      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6326                                 offset_addr))
6327        return false;
6328    }
6329  }
6330  return true;
6331}
6332
6333// LDRB (literal) calculates an address from the PC value and an immediate
6334// offset, loads a byte from memory,
6335// zero-extends it to form a 32-bit word and writes it to a register.
6336bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
6337                                               const ARMEncoding encoding) {
6338#if 0
6339    if ConditionPassed() then
6340        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6341        base = Align(PC,4);
6342        address = if add then (base + imm32) else (base - imm32);
6343        R[t] = ZeroExtend(MemU[address,1], 32);
6344#endif
6345
6346  bool success = false;
6347
6348  if (ConditionPassed(opcode)) {
6349    uint32_t t;
6350    uint32_t imm32;
6351    bool add;
6352    switch (encoding) {
6353    case eEncodingT1:
6354      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6355      t = Bits32(opcode, 15, 12);
6356      imm32 = Bits32(opcode, 11, 0);
6357      add = BitIsSet(opcode, 23);
6358
6359      // if Rt == '1111' then SEE PLD;
6360      if (t == 15)
6361        return false; // PLD is not implemented yet
6362
6363      // if t == 13 then UNPREDICTABLE;
6364      if (t == 13)
6365        return false;
6366
6367      break;
6368
6369    case eEncodingA1:
6370      // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6371      t = Bits32(opcode, 15, 12);
6372      imm32 = Bits32(opcode, 11, 0);
6373      add = BitIsSet(opcode, 23);
6374
6375      // if t == 15 then UNPREDICTABLE;
6376      if (t == 15)
6377        return false;
6378      break;
6379
6380    default:
6381      return false;
6382    }
6383
6384    // base = Align(PC,4);
6385    uint32_t pc_val = ReadCoreReg(PC_REG, &success);
6386    if (!success)
6387      return false;
6388
6389    uint32_t base = AlignPC(pc_val);
6390
6391    addr_t address;
6392    // address = if add then (base + imm32) else (base - imm32);
6393    if (add)
6394      address = base + imm32;
6395    else
6396      address = base - imm32;
6397
6398    // R[t] = ZeroExtend(MemU[address,1], 32);
6399    EmulateInstruction::Context context;
6400    context.type = eContextRelativeBranchImmediate;
6401    context.SetImmediate(address - base);
6402
6403    uint64_t data = MemURead(context, address, 1, 0, &success);
6404    if (!success)
6405      return false;
6406
6407    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6408      return false;
6409  }
6410  return true;
6411}
6412
6413// LDRB (register) calculates an address from a base register value and an
6414// offset rigister value, loads a byte from
6415// memory, zero-extends it to form a 32-bit word, and writes it to a register.
6416// The offset register value can
6417// optionally be shifted.
6418bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
6419                                                const ARMEncoding encoding) {
6420#if 0
6421    if ConditionPassed() then
6422        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6423        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6424        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6425        address = if index then offset_addr else R[n];
6426        R[t] = ZeroExtend(MemU[address,1],32);
6427        if wback then R[n] = offset_addr;
6428#endif
6429
6430  bool success = false;
6431
6432  if (ConditionPassed(opcode)) {
6433    uint32_t t;
6434    uint32_t n;
6435    uint32_t m;
6436    bool index;
6437    bool add;
6438    bool wback;
6439    ARM_ShifterType shift_t;
6440    uint32_t shift_n;
6441
6442    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6443    switch (encoding) {
6444    case eEncodingT1:
6445      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6446      t = Bits32(opcode, 2, 0);
6447      n = Bits32(opcode, 5, 3);
6448      m = Bits32(opcode, 8, 6);
6449
6450      // index = TRUE; add = TRUE; wback = FALSE;
6451      index = true;
6452      add = true;
6453      wback = false;
6454
6455      // (shift_t, shift_n) = (SRType_LSL, 0);
6456      shift_t = SRType_LSL;
6457      shift_n = 0;
6458      break;
6459
6460    case eEncodingT2:
6461      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6462      t = Bits32(opcode, 15, 12);
6463      n = Bits32(opcode, 19, 16);
6464      m = Bits32(opcode, 3, 0);
6465
6466      // index = TRUE; add = TRUE; wback = FALSE;
6467      index = true;
6468      add = true;
6469      wback = false;
6470
6471      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6472      shift_t = SRType_LSL;
6473      shift_n = Bits32(opcode, 5, 4);
6474
6475      // if Rt == '1111' then SEE PLD;
6476      if (t == 15)
6477        return false; // PLD is not implemented yet
6478
6479      // if Rn == '1111' then SEE LDRB (literal);
6480      if (n == 15)
6481        return EmulateLDRBLiteral(opcode, eEncodingT1);
6482
6483      // if t == 13 || BadReg(m) then UNPREDICTABLE;
6484      if ((t == 13) || BadReg(m))
6485        return false;
6486      break;
6487
6488    case eEncodingA1: {
6489      // if P == '0' && W == '1' then SEE LDRBT;
6490      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6491      t = Bits32(opcode, 15, 12);
6492      n = Bits32(opcode, 19, 16);
6493      m = Bits32(opcode, 3, 0);
6494
6495      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
6496      // (W == '1');
6497      index = BitIsSet(opcode, 24);
6498      add = BitIsSet(opcode, 23);
6499      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6500
6501      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6502      uint32_t type = Bits32(opcode, 6, 5);
6503      uint32_t imm5 = Bits32(opcode, 11, 7);
6504      shift_n = DecodeImmShift(type, imm5, shift_t);
6505
6506      // if t == 15 || m == 15 then UNPREDICTABLE;
6507      if ((t == 15) || (m == 15))
6508        return false;
6509
6510      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6511      if (wback && ((n == 15) || (n == t)))
6512        return false;
6513    } break;
6514
6515    default:
6516      return false;
6517    }
6518
6519    addr_t offset_addr;
6520    addr_t address;
6521
6522    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6523    uint32_t Rm =
6524        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6525    if (!success)
6526      return false;
6527
6528    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
6529    if (!success)
6530      return false;
6531
6532    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6533    uint32_t Rn =
6534        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6535    if (!success)
6536      return false;
6537
6538    if (add)
6539      offset_addr = Rn + offset;
6540    else
6541      offset_addr = Rn - offset;
6542
6543    // address = if index then offset_addr else R[n];
6544    if (index)
6545      address = offset_addr;
6546    else
6547      address = Rn;
6548
6549    // R[t] = ZeroExtend(MemU[address,1],32);
6550    RegisterInfo base_reg;
6551    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6552
6553    EmulateInstruction::Context context;
6554    context.type = eContextRegisterLoad;
6555    context.SetRegisterPlusOffset(base_reg, address - Rn);
6556
6557    uint64_t data = MemURead(context, address, 1, 0, &success);
6558    if (!success)
6559      return false;
6560
6561    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
6562      return false;
6563
6564    // if wback then R[n] = offset_addr;
6565    if (wback) {
6566      context.type = eContextAdjustBaseRegister;
6567      context.SetAddress(offset_addr);
6568      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6569                                 offset_addr))
6570        return false;
6571    }
6572  }
6573  return true;
6574}
6575
6576// LDRH (immediate, Thumb) calculates an address from a base register value and
6577// an immediate offset, loads a
6578// halfword from memory, zero-extends it to form a 32-bit word, and writes it to
6579// a register.  It can use offset,
6580// post-indexed, or pre-indexed addressing.
6581bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
6582                                                 const ARMEncoding encoding) {
6583#if 0
6584    if ConditionPassed() then
6585        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6586        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6587        address = if index then offset_addr else R[n];
6588        data = MemU[address,2];
6589        if wback then R[n] = offset_addr;
6590        if UnalignedSupport() || address<0> = '0' then
6591            R[t] = ZeroExtend(data, 32);
6592        else // Can only apply before ARMv7
6593            R[t] = bits(32) UNKNOWN;
6594#endif
6595
6596  bool success = false;
6597
6598  if (ConditionPassed(opcode)) {
6599    uint32_t t;
6600    uint32_t n;
6601    uint32_t imm32;
6602    bool index;
6603    bool add;
6604    bool wback;
6605
6606    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6607    switch (encoding) {
6608    case eEncodingT1:
6609      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6610      t = Bits32(opcode, 2, 0);
6611      n = Bits32(opcode, 5, 3);
6612      imm32 = Bits32(opcode, 10, 6) << 1;
6613
6614      // index = TRUE; add = TRUE; wback = FALSE;
6615      index = true;
6616      add = true;
6617      wback = false;
6618
6619      break;
6620
6621    case eEncodingT2:
6622      // if Rt == '1111' then SEE "Unallocated memory hints";
6623      // if Rn == '1111' then SEE LDRH (literal);
6624      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6625      t = Bits32(opcode, 15, 12);
6626      n = Bits32(opcode, 19, 16);
6627      imm32 = Bits32(opcode, 11, 0);
6628
6629      // index = TRUE; add = TRUE; wback = FALSE;
6630      index = true;
6631      add = true;
6632      wback = false;
6633
6634      // if t == 13 then UNPREDICTABLE;
6635      if (t == 13)
6636        return false;
6637      break;
6638
6639    case eEncodingT3:
6640      // if Rn == '1111' then SEE LDRH (literal);
6641      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
6642      // "Unallocated memory hints";
6643      // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6644      // if P == '0' && W == '0' then UNDEFINED;
6645      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
6646        return false;
6647
6648      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6649      t = Bits32(opcode, 15, 12);
6650      n = Bits32(opcode, 19, 16);
6651      imm32 = Bits32(opcode, 7, 0);
6652
6653      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6654      index = BitIsSet(opcode, 10);
6655      add = BitIsSet(opcode, 9);
6656      wback = BitIsSet(opcode, 8);
6657
6658      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6659      if (BadReg(t) || (wback && (n == t)))
6660        return false;
6661      break;
6662
6663    default:
6664      return false;
6665    }
6666
6667    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6668    uint32_t Rn =
6669        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6670    if (!success)
6671      return false;
6672
6673    addr_t offset_addr;
6674    addr_t address;
6675
6676    if (add)
6677      offset_addr = Rn + imm32;
6678    else
6679      offset_addr = Rn - imm32;
6680
6681    // address = if index then offset_addr else R[n];
6682    if (index)
6683      address = offset_addr;
6684    else
6685      address = Rn;
6686
6687    // data = MemU[address,2];
6688    RegisterInfo base_reg;
6689    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6690
6691    EmulateInstruction::Context context;
6692    context.type = eContextRegisterLoad;
6693    context.SetRegisterPlusOffset(base_reg, address - Rn);
6694
6695    uint64_t data = MemURead(context, address, 2, 0, &success);
6696    if (!success)
6697      return false;
6698
6699    // if wback then R[n] = offset_addr;
6700    if (wback) {
6701      context.type = eContextAdjustBaseRegister;
6702      context.SetAddress(offset_addr);
6703      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6704                                 offset_addr))
6705        return false;
6706    }
6707
6708    // if UnalignedSupport() || address<0> = '0' then
6709    if (UnalignedSupport() || BitIsClear(address, 0)) {
6710      // R[t] = ZeroExtend(data, 32);
6711      context.type = eContextRegisterLoad;
6712      context.SetRegisterPlusOffset(base_reg, address - Rn);
6713      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6714                                 data))
6715        return false;
6716    } else // Can only apply before ARMv7
6717    {
6718      // R[t] = bits(32) UNKNOWN;
6719      WriteBits32Unknown(t);
6720    }
6721  }
6722  return true;
6723}
6724
6725// LDRH (literal) caculates an address from the PC value and an immediate
6726// offset, loads a halfword from memory,
6727// zero-extends it to form a 32-bit word, and writes it to a register.
6728bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
6729                                               const ARMEncoding encoding) {
6730#if 0
6731    if ConditionPassed() then
6732        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6733        base = Align(PC,4);
6734        address = if add then (base + imm32) else (base - imm32);
6735        data = MemU[address,2];
6736        if UnalignedSupport() || address<0> = '0' then
6737            R[t] = ZeroExtend(data, 32);
6738        else // Can only apply before ARMv7
6739            R[t] = bits(32) UNKNOWN;
6740#endif
6741
6742  bool success = false;
6743
6744  if (ConditionPassed(opcode)) {
6745    uint32_t t;
6746    uint32_t imm32;
6747    bool add;
6748
6749    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6750    switch (encoding) {
6751    case eEncodingT1:
6752      // if Rt == '1111' then SEE "Unallocated memory hints";
6753      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6754      t = Bits32(opcode, 15, 12);
6755      imm32 = Bits32(opcode, 11, 0);
6756      add = BitIsSet(opcode, 23);
6757
6758      // if t == 13 then UNPREDICTABLE;
6759      if (t == 13)
6760        return false;
6761
6762      break;
6763
6764    case eEncodingA1: {
6765      uint32_t imm4H = Bits32(opcode, 11, 8);
6766      uint32_t imm4L = Bits32(opcode, 3, 0);
6767
6768      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6769      t = Bits32(opcode, 15, 12);
6770      imm32 = (imm4H << 4) | imm4L;
6771      add = BitIsSet(opcode, 23);
6772
6773      // if t == 15 then UNPREDICTABLE;
6774      if (t == 15)
6775        return false;
6776      break;
6777    }
6778
6779    default:
6780      return false;
6781    }
6782
6783    // base = Align(PC,4);
6784    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
6785    if (!success)
6786      return false;
6787
6788    addr_t base = AlignPC(pc_value);
6789    addr_t address;
6790
6791    // address = if add then (base + imm32) else (base - imm32);
6792    if (add)
6793      address = base + imm32;
6794    else
6795      address = base - imm32;
6796
6797    // data = MemU[address,2];
6798    RegisterInfo base_reg;
6799    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6800
6801    EmulateInstruction::Context context;
6802    context.type = eContextRegisterLoad;
6803    context.SetRegisterPlusOffset(base_reg, address - base);
6804
6805    uint64_t data = MemURead(context, address, 2, 0, &success);
6806    if (!success)
6807      return false;
6808
6809    // if UnalignedSupport() || address<0> = '0' then
6810    if (UnalignedSupport() || BitIsClear(address, 0)) {
6811      // R[t] = ZeroExtend(data, 32);
6812      context.type = eContextRegisterLoad;
6813      context.SetRegisterPlusOffset(base_reg, address - base);
6814      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6815                                 data))
6816        return false;
6817
6818    } else // Can only apply before ARMv7
6819    {
6820      // R[t] = bits(32) UNKNOWN;
6821      WriteBits32Unknown(t);
6822    }
6823  }
6824  return true;
6825}
6826
6827// LDRH (literal) calculates an address from a base register value and an offset
6828// register value, loads a halfword
6829// from memory, zero-extends it to form a 32-bit word, and writes it to a
6830// register.  The offset register value can
6831// be shifted left by 0, 1, 2, or 3 bits.
6832bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
6833                                                const ARMEncoding encoding) {
6834#if 0
6835    if ConditionPassed() then
6836        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6837        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6838        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6839        address = if index then offset_addr else R[n];
6840        data = MemU[address,2];
6841        if wback then R[n] = offset_addr;
6842        if UnalignedSupport() || address<0> = '0' then
6843            R[t] = ZeroExtend(data, 32);
6844        else // Can only apply before ARMv7
6845            R[t] = bits(32) UNKNOWN;
6846#endif
6847
6848  bool success = false;
6849
6850  if (ConditionPassed(opcode)) {
6851    uint32_t t;
6852    uint32_t n;
6853    uint32_t m;
6854    bool index;
6855    bool add;
6856    bool wback;
6857    ARM_ShifterType shift_t;
6858    uint32_t shift_n;
6859
6860    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6861    switch (encoding) {
6862    case eEncodingT1:
6863      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
6864      // in ThumbEE";
6865      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6866      t = Bits32(opcode, 2, 0);
6867      n = Bits32(opcode, 5, 3);
6868      m = Bits32(opcode, 8, 6);
6869
6870      // index = TRUE; add = TRUE; wback = FALSE;
6871      index = true;
6872      add = true;
6873      wback = false;
6874
6875      // (shift_t, shift_n) = (SRType_LSL, 0);
6876      shift_t = SRType_LSL;
6877      shift_n = 0;
6878
6879      break;
6880
6881    case eEncodingT2:
6882      // if Rn == '1111' then SEE LDRH (literal);
6883      // if Rt == '1111' then SEE "Unallocated memory hints";
6884      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6885      t = Bits32(opcode, 15, 12);
6886      n = Bits32(opcode, 19, 16);
6887      m = Bits32(opcode, 3, 0);
6888
6889      // index = TRUE; add = TRUE; wback = FALSE;
6890      index = true;
6891      add = true;
6892      wback = false;
6893
6894      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6895      shift_t = SRType_LSL;
6896      shift_n = Bits32(opcode, 5, 4);
6897
6898      // if t == 13 || BadReg(m) then UNPREDICTABLE;
6899      if ((t == 13) || BadReg(m))
6900        return false;
6901      break;
6902
6903    case eEncodingA1:
6904      // if P == '0' && W == '1' then SEE LDRHT;
6905      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6906      t = Bits32(opcode, 15, 12);
6907      n = Bits32(opcode, 19, 16);
6908      m = Bits32(opcode, 3, 0);
6909
6910      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
6911      // (W == '1');
6912      index = BitIsSet(opcode, 24);
6913      add = BitIsSet(opcode, 23);
6914      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
6915
6916      // (shift_t, shift_n) = (SRType_LSL, 0);
6917      shift_t = SRType_LSL;
6918      shift_n = 0;
6919
6920      // if t == 15 || m == 15 then UNPREDICTABLE;
6921      if ((t == 15) || (m == 15))
6922        return false;
6923
6924      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6925      if (wback && ((n == 15) || (n == t)))
6926        return false;
6927
6928      break;
6929
6930    default:
6931      return false;
6932    }
6933
6934    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6935
6936    uint64_t Rm =
6937        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6938    if (!success)
6939      return false;
6940
6941    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
6942    if (!success)
6943      return false;
6944
6945    addr_t offset_addr;
6946    addr_t address;
6947
6948    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6949    uint64_t Rn =
6950        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6951    if (!success)
6952      return false;
6953
6954    if (add)
6955      offset_addr = Rn + offset;
6956    else
6957      offset_addr = Rn - offset;
6958
6959    // address = if index then offset_addr else R[n];
6960    if (index)
6961      address = offset_addr;
6962    else
6963      address = Rn;
6964
6965    // data = MemU[address,2];
6966    RegisterInfo base_reg;
6967    RegisterInfo offset_reg;
6968    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6969    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6970
6971    EmulateInstruction::Context context;
6972    context.type = eContextRegisterLoad;
6973    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
6974    uint64_t data = MemURead(context, address, 2, 0, &success);
6975    if (!success)
6976      return false;
6977
6978    // if wback then R[n] = offset_addr;
6979    if (wback) {
6980      context.type = eContextAdjustBaseRegister;
6981      context.SetAddress(offset_addr);
6982      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
6983                                 offset_addr))
6984        return false;
6985    }
6986
6987    // if UnalignedSupport() || address<0> = '0' then
6988    if (UnalignedSupport() || BitIsClear(address, 0)) {
6989      // R[t] = ZeroExtend(data, 32);
6990      context.type = eContextRegisterLoad;
6991      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
6992      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
6993                                 data))
6994        return false;
6995    } else // Can only apply before ARMv7
6996    {
6997      // R[t] = bits(32) UNKNOWN;
6998      WriteBits32Unknown(t);
6999    }
7000  }
7001  return true;
7002}
7003
7004// LDRSB (immediate) calculates an address from a base register value and an
7005// immediate offset, loads a byte from
7006// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7007// It can use offset, post-indexed,
7008// or pre-indexed addressing.
7009bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
7010                                                  const ARMEncoding encoding) {
7011#if 0
7012    if ConditionPassed() then
7013        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7014        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7015        address = if index then offset_addr else R[n];
7016        R[t] = SignExtend(MemU[address,1], 32);
7017        if wback then R[n] = offset_addr;
7018#endif
7019
7020  bool success = false;
7021
7022  if (ConditionPassed(opcode)) {
7023    uint32_t t;
7024    uint32_t n;
7025    uint32_t imm32;
7026    bool index;
7027    bool add;
7028    bool wback;
7029
7030    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7031    switch (encoding) {
7032    case eEncodingT1:
7033      // if Rt == '1111' then SEE PLI;
7034      // if Rn == '1111' then SEE LDRSB (literal);
7035      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7036      t = Bits32(opcode, 15, 12);
7037      n = Bits32(opcode, 19, 16);
7038      imm32 = Bits32(opcode, 11, 0);
7039
7040      // index = TRUE; add = TRUE; wback = FALSE;
7041      index = true;
7042      add = true;
7043      wback = false;
7044
7045      // if t == 13 then UNPREDICTABLE;
7046      if (t == 13)
7047        return false;
7048
7049      break;
7050
7051    case eEncodingT2:
7052      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7053      // if Rn == '1111' then SEE LDRSB (literal);
7054      // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7055      // if P == '0' && W == '0' then UNDEFINED;
7056      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7057        return false;
7058
7059      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7060      t = Bits32(opcode, 15, 12);
7061      n = Bits32(opcode, 19, 16);
7062      imm32 = Bits32(opcode, 7, 0);
7063
7064      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7065      index = BitIsSet(opcode, 10);
7066      add = BitIsSet(opcode, 9);
7067      wback = BitIsSet(opcode, 8);
7068
7069      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7070      if (((t == 13) ||
7071           ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
7072                          BitIsSet(opcode, 8)))) ||
7073          (wback && (n == t)))
7074        return false;
7075
7076      break;
7077
7078    case eEncodingA1: {
7079      // if Rn == '1111' then SEE LDRSB (literal);
7080      // if P == '0' && W == '1' then SEE LDRSBT;
7081      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7082      t = Bits32(opcode, 15, 12);
7083      n = Bits32(opcode, 19, 16);
7084
7085      uint32_t imm4H = Bits32(opcode, 11, 8);
7086      uint32_t imm4L = Bits32(opcode, 3, 0);
7087      imm32 = (imm4H << 4) | imm4L;
7088
7089      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7090      // (W == '1');
7091      index = BitIsSet(opcode, 24);
7092      add = BitIsSet(opcode, 23);
7093      wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
7094
7095      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7096      if ((t == 15) || (wback && (n == t)))
7097        return false;
7098
7099      break;
7100    }
7101
7102    default:
7103      return false;
7104    }
7105
7106    uint64_t Rn = ReadCoreReg(n, &success);
7107    if (!success)
7108      return false;
7109
7110    addr_t offset_addr;
7111    addr_t address;
7112
7113    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7114    if (add)
7115      offset_addr = Rn + imm32;
7116    else
7117      offset_addr = Rn - imm32;
7118
7119    // address = if index then offset_addr else R[n];
7120    if (index)
7121      address = offset_addr;
7122    else
7123      address = Rn;
7124
7125    // R[t] = SignExtend(MemU[address,1], 32);
7126    RegisterInfo base_reg;
7127    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7128
7129    EmulateInstruction::Context context;
7130    context.type = eContextRegisterLoad;
7131    context.SetRegisterPlusOffset(base_reg, address - Rn);
7132
7133    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7134    if (!success)
7135      return false;
7136
7137    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7138    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7139                               (uint64_t)signed_data))
7140      return false;
7141
7142    // if wback then R[n] = offset_addr;
7143    if (wback) {
7144      context.type = eContextAdjustBaseRegister;
7145      context.SetAddress(offset_addr);
7146      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7147                                 offset_addr))
7148        return false;
7149    }
7150  }
7151
7152  return true;
7153}
7154
7155// LDRSB (literal) calculates an address from the PC value and an immediate
7156// offset, loads a byte from memory,
7157// sign-extends it to form a 32-bit word, and writes tit to a register.
7158bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
7159                                                const ARMEncoding encoding) {
7160#if 0
7161    if ConditionPassed() then
7162        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7163        base = Align(PC,4);
7164        address = if add then (base + imm32) else (base - imm32);
7165        R[t] = SignExtend(MemU[address,1], 32);
7166#endif
7167
7168  bool success = false;
7169
7170  if (ConditionPassed(opcode)) {
7171    uint32_t t;
7172    uint32_t imm32;
7173    bool add;
7174
7175    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7176    switch (encoding) {
7177    case eEncodingT1:
7178      // if Rt == '1111' then SEE PLI;
7179      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7180      t = Bits32(opcode, 15, 12);
7181      imm32 = Bits32(opcode, 11, 0);
7182      add = BitIsSet(opcode, 23);
7183
7184      // if t == 13 then UNPREDICTABLE;
7185      if (t == 13)
7186        return false;
7187
7188      break;
7189
7190    case eEncodingA1: {
7191      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7192      t = Bits32(opcode, 15, 12);
7193      uint32_t imm4H = Bits32(opcode, 11, 8);
7194      uint32_t imm4L = Bits32(opcode, 3, 0);
7195      imm32 = (imm4H << 4) | imm4L;
7196      add = BitIsSet(opcode, 23);
7197
7198      // if t == 15 then UNPREDICTABLE;
7199      if (t == 15)
7200        return false;
7201
7202      break;
7203    }
7204
7205    default:
7206      return false;
7207    }
7208
7209    // base = Align(PC,4);
7210    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7211    if (!success)
7212      return false;
7213    uint64_t base = AlignPC(pc_value);
7214
7215    // address = if add then (base + imm32) else (base - imm32);
7216    addr_t address;
7217    if (add)
7218      address = base + imm32;
7219    else
7220      address = base - imm32;
7221
7222    // R[t] = SignExtend(MemU[address,1], 32);
7223    RegisterInfo base_reg;
7224    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7225
7226    EmulateInstruction::Context context;
7227    context.type = eContextRegisterLoad;
7228    context.SetRegisterPlusOffset(base_reg, address - base);
7229
7230    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7231    if (!success)
7232      return false;
7233
7234    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7235    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7236                               (uint64_t)signed_data))
7237      return false;
7238  }
7239  return true;
7240}
7241
7242// LDRSB (register) calculates an address from a base register value and an
7243// offset register value, loadsa byte from
7244// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7245// The offset register value can be
7246// shifted left by 0, 1, 2, or 3 bits.
7247bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
7248                                                 const ARMEncoding encoding) {
7249#if 0
7250    if ConditionPassed() then
7251        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7252        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7253        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7254        address = if index then offset_addr else R[n];
7255        R[t] = SignExtend(MemU[address,1], 32);
7256        if wback then R[n] = offset_addr;
7257#endif
7258
7259  bool success = false;
7260
7261  if (ConditionPassed(opcode)) {
7262    uint32_t t;
7263    uint32_t n;
7264    uint32_t m;
7265    bool index;
7266    bool add;
7267    bool wback;
7268    ARM_ShifterType shift_t;
7269    uint32_t shift_n;
7270
7271    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7272    switch (encoding) {
7273    case eEncodingT1:
7274      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7275      t = Bits32(opcode, 2, 0);
7276      n = Bits32(opcode, 5, 3);
7277      m = Bits32(opcode, 8, 6);
7278
7279      // index = TRUE; add = TRUE; wback = FALSE;
7280      index = true;
7281      add = true;
7282      wback = false;
7283
7284      // (shift_t, shift_n) = (SRType_LSL, 0);
7285      shift_t = SRType_LSL;
7286      shift_n = 0;
7287
7288      break;
7289
7290    case eEncodingT2:
7291      // if Rt == '1111' then SEE PLI;
7292      // if Rn == '1111' then SEE LDRSB (literal);
7293      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7294      t = Bits32(opcode, 15, 12);
7295      n = Bits32(opcode, 19, 16);
7296      m = Bits32(opcode, 3, 0);
7297
7298      // index = TRUE; add = TRUE; wback = FALSE;
7299      index = true;
7300      add = true;
7301      wback = false;
7302
7303      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7304      shift_t = SRType_LSL;
7305      shift_n = Bits32(opcode, 5, 4);
7306
7307      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7308      if ((t == 13) || BadReg(m))
7309        return false;
7310      break;
7311
7312    case eEncodingA1:
7313      // if P == '0' && W == '1' then SEE LDRSBT;
7314      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7315      t = Bits32(opcode, 15, 12);
7316      n = Bits32(opcode, 19, 16);
7317      m = Bits32(opcode, 3, 0);
7318
7319      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7320      // (W == '1');
7321      index = BitIsSet(opcode, 24);
7322      add = BitIsSet(opcode, 23);
7323      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7324
7325      // (shift_t, shift_n) = (SRType_LSL, 0);
7326      shift_t = SRType_LSL;
7327      shift_n = 0;
7328
7329      // if t == 15 || m == 15 then UNPREDICTABLE;
7330      if ((t == 15) || (m == 15))
7331        return false;
7332
7333      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7334      if (wback && ((n == 15) || (n == t)))
7335        return false;
7336      break;
7337
7338    default:
7339      return false;
7340    }
7341
7342    uint64_t Rm =
7343        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7344    if (!success)
7345      return false;
7346
7347    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7348    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7349    if (!success)
7350      return false;
7351
7352    addr_t offset_addr;
7353    addr_t address;
7354
7355    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7356    uint64_t Rn =
7357        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7358    if (!success)
7359      return false;
7360
7361    if (add)
7362      offset_addr = Rn + offset;
7363    else
7364      offset_addr = Rn - offset;
7365
7366    // address = if index then offset_addr else R[n];
7367    if (index)
7368      address = offset_addr;
7369    else
7370      address = Rn;
7371
7372    // R[t] = SignExtend(MemU[address,1], 32);
7373    RegisterInfo base_reg;
7374    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7375    RegisterInfo offset_reg;
7376    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7377
7378    EmulateInstruction::Context context;
7379    context.type = eContextRegisterLoad;
7380    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7381
7382    uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
7383    if (!success)
7384      return false;
7385
7386    int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7387    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7388                               (uint64_t)signed_data))
7389      return false;
7390
7391    // if wback then R[n] = offset_addr;
7392    if (wback) {
7393      context.type = eContextAdjustBaseRegister;
7394      context.SetAddress(offset_addr);
7395      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7396                                 offset_addr))
7397        return false;
7398    }
7399  }
7400  return true;
7401}
7402
7403// LDRSH (immediate) calculates an address from a base register value and an
7404// immediate offset, loads a halfword from
7405// memory, sign-extends it to form a 32-bit word, and writes it to a register.
7406// It can use offset, post-indexed, or
7407// pre-indexed addressing.
7408bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
7409                                                  const ARMEncoding encoding) {
7410#if 0
7411    if ConditionPassed() then
7412        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7413        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7414        address = if index then offset_addr else R[n];
7415        data = MemU[address,2];
7416        if wback then R[n] = offset_addr;
7417        if UnalignedSupport() || address<0> = '0' then
7418            R[t] = SignExtend(data, 32);
7419        else // Can only apply before ARMv7
7420            R[t] = bits(32) UNKNOWN;
7421#endif
7422
7423  bool success = false;
7424
7425  if (ConditionPassed(opcode)) {
7426    uint32_t t;
7427    uint32_t n;
7428    uint32_t imm32;
7429    bool index;
7430    bool add;
7431    bool wback;
7432
7433    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7434    switch (encoding) {
7435    case eEncodingT1:
7436      // if Rn == '1111' then SEE LDRSH (literal);
7437      // if Rt == '1111' then SEE "Unallocated memory hints";
7438      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7439      t = Bits32(opcode, 15, 12);
7440      n = Bits32(opcode, 19, 16);
7441      imm32 = Bits32(opcode, 11, 0);
7442
7443      // index = TRUE; add = TRUE; wback = FALSE;
7444      index = true;
7445      add = true;
7446      wback = false;
7447
7448      // if t == 13 then UNPREDICTABLE;
7449      if (t == 13)
7450        return false;
7451
7452      break;
7453
7454    case eEncodingT2:
7455      // if Rn == '1111' then SEE LDRSH (literal);
7456      // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
7457      // "Unallocated memory hints";
7458      // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7459      // if P == '0' && W == '0' then UNDEFINED;
7460      if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
7461        return false;
7462
7463      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7464      t = Bits32(opcode, 15, 12);
7465      n = Bits32(opcode, 19, 16);
7466      imm32 = Bits32(opcode, 7, 0);
7467
7468      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7469      index = BitIsSet(opcode, 10);
7470      add = BitIsSet(opcode, 9);
7471      wback = BitIsSet(opcode, 8);
7472
7473      // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7474      if (BadReg(t) || (wback && (n == t)))
7475        return false;
7476
7477      break;
7478
7479    case eEncodingA1: {
7480      // if Rn == '1111' then SEE LDRSH (literal);
7481      // if P == '0' && W == '1' then SEE LDRSHT;
7482      // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7483      t = Bits32(opcode, 15, 12);
7484      n = Bits32(opcode, 19, 16);
7485      uint32_t imm4H = Bits32(opcode, 11, 8);
7486      uint32_t imm4L = Bits32(opcode, 3, 0);
7487      imm32 = (imm4H << 4) | imm4L;
7488
7489      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7490      // (W == '1');
7491      index = BitIsSet(opcode, 24);
7492      add = BitIsSet(opcode, 23);
7493      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7494
7495      // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7496      if ((t == 15) || (wback && (n == t)))
7497        return false;
7498
7499      break;
7500    }
7501
7502    default:
7503      return false;
7504    }
7505
7506    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7507    uint64_t Rn =
7508        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7509    if (!success)
7510      return false;
7511
7512    addr_t offset_addr;
7513    if (add)
7514      offset_addr = Rn + imm32;
7515    else
7516      offset_addr = Rn - imm32;
7517
7518    // address = if index then offset_addr else R[n];
7519    addr_t address;
7520    if (index)
7521      address = offset_addr;
7522    else
7523      address = Rn;
7524
7525    // data = MemU[address,2];
7526    RegisterInfo base_reg;
7527    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7528
7529    EmulateInstruction::Context context;
7530    context.type = eContextRegisterLoad;
7531    context.SetRegisterPlusOffset(base_reg, address - Rn);
7532
7533    uint64_t data = MemURead(context, address, 2, 0, &success);
7534    if (!success)
7535      return false;
7536
7537    // if wback then R[n] = offset_addr;
7538    if (wback) {
7539      context.type = eContextAdjustBaseRegister;
7540      context.SetAddress(offset_addr);
7541      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7542                                 offset_addr))
7543        return false;
7544    }
7545
7546    // if UnalignedSupport() || address<0> = '0' then
7547    if (UnalignedSupport() || BitIsClear(address, 0)) {
7548      // R[t] = SignExtend(data, 32);
7549      int64_t signed_data = llvm::SignExtend64<16>(data);
7550      context.type = eContextRegisterLoad;
7551      context.SetRegisterPlusOffset(base_reg, address - Rn);
7552      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7553                                 (uint64_t)signed_data))
7554        return false;
7555    } else // Can only apply before ARMv7
7556    {
7557      // R[t] = bits(32) UNKNOWN;
7558      WriteBits32Unknown(t);
7559    }
7560  }
7561  return true;
7562}
7563
7564// LDRSH (literal) calculates an address from the PC value and an immediate
7565// offset, loads a halfword from memory,
7566// sign-extends it to from a 32-bit word, and writes it to a register.
7567bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
7568                                                const ARMEncoding encoding) {
7569#if 0
7570    if ConditionPassed() then
7571        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7572        base = Align(PC,4);
7573        address = if add then (base + imm32) else (base - imm32);
7574        data = MemU[address,2];
7575        if UnalignedSupport() || address<0> = '0' then
7576            R[t] = SignExtend(data, 32);
7577        else // Can only apply before ARMv7
7578            R[t] = bits(32) UNKNOWN;
7579#endif
7580
7581  bool success = false;
7582
7583  if (ConditionPassed(opcode)) {
7584    uint32_t t;
7585    uint32_t imm32;
7586    bool add;
7587
7588    // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7589    switch (encoding) {
7590    case eEncodingT1:
7591      // if Rt == '1111' then SEE "Unallocated memory hints";
7592      // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7593      t = Bits32(opcode, 15, 12);
7594      imm32 = Bits32(opcode, 11, 0);
7595      add = BitIsSet(opcode, 23);
7596
7597      // if t == 13 then UNPREDICTABLE;
7598      if (t == 13)
7599        return false;
7600
7601      break;
7602
7603    case eEncodingA1: {
7604      // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7605      t = Bits32(opcode, 15, 12);
7606      uint32_t imm4H = Bits32(opcode, 11, 8);
7607      uint32_t imm4L = Bits32(opcode, 3, 0);
7608      imm32 = (imm4H << 4) | imm4L;
7609      add = BitIsSet(opcode, 23);
7610
7611      // if t == 15 then UNPREDICTABLE;
7612      if (t == 15)
7613        return false;
7614
7615      break;
7616    }
7617    default:
7618      return false;
7619    }
7620
7621    // base = Align(PC,4);
7622    uint64_t pc_value = ReadCoreReg(PC_REG, &success);
7623    if (!success)
7624      return false;
7625
7626    uint64_t base = AlignPC(pc_value);
7627
7628    addr_t address;
7629    // address = if add then (base + imm32) else (base - imm32);
7630    if (add)
7631      address = base + imm32;
7632    else
7633      address = base - imm32;
7634
7635    // data = MemU[address,2];
7636    RegisterInfo base_reg;
7637    GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7638
7639    EmulateInstruction::Context context;
7640    context.type = eContextRegisterLoad;
7641    context.SetRegisterPlusOffset(base_reg, imm32);
7642
7643    uint64_t data = MemURead(context, address, 2, 0, &success);
7644    if (!success)
7645      return false;
7646
7647    // if UnalignedSupport() || address<0> = '0' then
7648    if (UnalignedSupport() || BitIsClear(address, 0)) {
7649      // R[t] = SignExtend(data, 32);
7650      int64_t signed_data = llvm::SignExtend64<16>(data);
7651      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7652                                 (uint64_t)signed_data))
7653        return false;
7654    } else // Can only apply before ARMv7
7655    {
7656      // R[t] = bits(32) UNKNOWN;
7657      WriteBits32Unknown(t);
7658    }
7659  }
7660  return true;
7661}
7662
7663// LDRSH (register) calculates an address from a base register value and an
7664// offset register value, loads a halfword
7665// from memory, sign-extends it to form a 32-bit word, and writes it to a
7666// register.  The offset register value can be
7667// shifted left by 0, 1, 2, or 3 bits.
7668bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
7669                                                 const ARMEncoding encoding) {
7670#if 0
7671    if ConditionPassed() then
7672        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7673        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7674        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7675        address = if index then offset_addr else R[n];
7676        data = MemU[address,2];
7677        if wback then R[n] = offset_addr;
7678        if UnalignedSupport() || address<0> = '0' then
7679            R[t] = SignExtend(data, 32);
7680        else // Can only apply before ARMv7
7681            R[t] = bits(32) UNKNOWN;
7682#endif
7683
7684  bool success = false;
7685
7686  if (ConditionPassed(opcode)) {
7687    uint32_t t;
7688    uint32_t n;
7689    uint32_t m;
7690    bool index;
7691    bool add;
7692    bool wback;
7693    ARM_ShifterType shift_t;
7694    uint32_t shift_n;
7695
7696    // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7697    switch (encoding) {
7698    case eEncodingT1:
7699      // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
7700      // in ThumbEE";
7701      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7702      t = Bits32(opcode, 2, 0);
7703      n = Bits32(opcode, 5, 3);
7704      m = Bits32(opcode, 8, 6);
7705
7706      // index = TRUE; add = TRUE; wback = FALSE;
7707      index = true;
7708      add = true;
7709      wback = false;
7710
7711      // (shift_t, shift_n) = (SRType_LSL, 0);
7712      shift_t = SRType_LSL;
7713      shift_n = 0;
7714
7715      break;
7716
7717    case eEncodingT2:
7718      // if Rn == '1111' then SEE LDRSH (literal);
7719      // if Rt == '1111' then SEE "Unallocated memory hints";
7720      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7721      t = Bits32(opcode, 15, 12);
7722      n = Bits32(opcode, 19, 16);
7723      m = Bits32(opcode, 3, 0);
7724
7725      // index = TRUE; add = TRUE; wback = FALSE;
7726      index = true;
7727      add = true;
7728      wback = false;
7729
7730      // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7731      shift_t = SRType_LSL;
7732      shift_n = Bits32(opcode, 5, 4);
7733
7734      // if t == 13 || BadReg(m) then UNPREDICTABLE;
7735      if ((t == 13) || BadReg(m))
7736        return false;
7737
7738      break;
7739
7740    case eEncodingA1:
7741      // if P == '0' && W == '1' then SEE LDRSHT;
7742      // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7743      t = Bits32(opcode, 15, 12);
7744      n = Bits32(opcode, 19, 16);
7745      m = Bits32(opcode, 3, 0);
7746
7747      // index = (P == '1');	add = (U == '1');	wback = (P == '0') ||
7748      // (W == '1');
7749      index = BitIsSet(opcode, 24);
7750      add = BitIsSet(opcode, 23);
7751      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
7752
7753      // (shift_t, shift_n) = (SRType_LSL, 0);
7754      shift_t = SRType_LSL;
7755      shift_n = 0;
7756
7757      // if t == 15 || m == 15 then UNPREDICTABLE;
7758      if ((t == 15) || (m == 15))
7759        return false;
7760
7761      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7762      if (wback && ((n == 15) || (n == t)))
7763        return false;
7764
7765      break;
7766
7767    default:
7768      return false;
7769    }
7770
7771    uint64_t Rm =
7772        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7773    if (!success)
7774      return false;
7775
7776    uint64_t Rn =
7777        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7778    if (!success)
7779      return false;
7780
7781    // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7782    addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
7783    if (!success)
7784      return false;
7785
7786    addr_t offset_addr;
7787    addr_t address;
7788
7789    // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7790    if (add)
7791      offset_addr = Rn + offset;
7792    else
7793      offset_addr = Rn - offset;
7794
7795    // address = if index then offset_addr else R[n];
7796    if (index)
7797      address = offset_addr;
7798    else
7799      address = Rn;
7800
7801    // data = MemU[address,2];
7802    RegisterInfo base_reg;
7803    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7804
7805    RegisterInfo offset_reg;
7806    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7807
7808    EmulateInstruction::Context context;
7809    context.type = eContextRegisterLoad;
7810    context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7811
7812    uint64_t data = MemURead(context, address, 2, 0, &success);
7813    if (!success)
7814      return false;
7815
7816    // if wback then R[n] = offset_addr;
7817    if (wback) {
7818      context.type = eContextAdjustBaseRegister;
7819      context.SetAddress(offset_addr);
7820      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
7821                                 offset_addr))
7822        return false;
7823    }
7824
7825    // if UnalignedSupport() || address<0> = '0' then
7826    if (UnalignedSupport() || BitIsClear(address, 0)) {
7827      // R[t] = SignExtend(data, 32);
7828      context.type = eContextRegisterLoad;
7829      context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
7830
7831      int64_t signed_data = llvm::SignExtend64<16>(data);
7832      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
7833                                 (uint64_t)signed_data))
7834        return false;
7835    } else // Can only apply before ARMv7
7836    {
7837      // R[t] = bits(32) UNKNOWN;
7838      WriteBits32Unknown(t);
7839    }
7840  }
7841  return true;
7842}
7843
7844// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
7845// writes the result to the destination
7846// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before
7847// extracting the 8-bit value.
7848bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
7849                                        const ARMEncoding encoding) {
7850#if 0
7851    if ConditionPassed() then
7852        EncodingSpecificOperations();
7853        rotated = ROR(R[m], rotation);
7854        R[d] = SignExtend(rotated<7:0>, 32);
7855#endif
7856
7857  bool success = false;
7858
7859  if (ConditionPassed(opcode)) {
7860    uint32_t d;
7861    uint32_t m;
7862    uint32_t rotation;
7863
7864    // EncodingSpecificOperations();
7865    switch (encoding) {
7866    case eEncodingT1:
7867      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7868      d = Bits32(opcode, 2, 0);
7869      m = Bits32(opcode, 5, 3);
7870      rotation = 0;
7871
7872      break;
7873
7874    case eEncodingT2:
7875      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7876      d = Bits32(opcode, 11, 8);
7877      m = Bits32(opcode, 3, 0);
7878      rotation = Bits32(opcode, 5, 4) << 3;
7879
7880      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7881      if (BadReg(d) || BadReg(m))
7882        return false;
7883
7884      break;
7885
7886    case eEncodingA1:
7887      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7888      d = Bits32(opcode, 15, 12);
7889      m = Bits32(opcode, 3, 0);
7890      rotation = Bits32(opcode, 11, 10) << 3;
7891
7892      // if d == 15 || m == 15 then UNPREDICTABLE;
7893      if ((d == 15) || (m == 15))
7894        return false;
7895
7896      break;
7897
7898    default:
7899      return false;
7900    }
7901
7902    uint64_t Rm =
7903        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7904    if (!success)
7905      return false;
7906
7907    // rotated = ROR(R[m], rotation);
7908    uint64_t rotated = ROR(Rm, rotation, &success);
7909    if (!success)
7910      return false;
7911
7912    // R[d] = SignExtend(rotated<7:0>, 32);
7913    int64_t data = llvm::SignExtend64<8>(rotated);
7914
7915    RegisterInfo source_reg;
7916    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7917
7918    EmulateInstruction::Context context;
7919    context.type = eContextRegisterLoad;
7920    context.SetRegister(source_reg);
7921
7922    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
7923                               (uint64_t)data))
7924      return false;
7925  }
7926  return true;
7927}
7928
7929// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
7930// writes the result to the destination
7931// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
7932// extracting the 16-bit value.
7933bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
7934                                        const ARMEncoding encoding) {
7935#if 0
7936    if ConditionPassed() then
7937        EncodingSpecificOperations();
7938        rotated = ROR(R[m], rotation);
7939        R[d] = SignExtend(rotated<15:0>, 32);
7940#endif
7941
7942  bool success = false;
7943
7944  if (ConditionPassed(opcode)) {
7945    uint32_t d;
7946    uint32_t m;
7947    uint32_t rotation;
7948
7949    // EncodingSpecificOperations();
7950    switch (encoding) {
7951    case eEncodingT1:
7952      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7953      d = Bits32(opcode, 2, 0);
7954      m = Bits32(opcode, 5, 3);
7955      rotation = 0;
7956
7957      break;
7958
7959    case eEncodingT2:
7960      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7961      d = Bits32(opcode, 11, 8);
7962      m = Bits32(opcode, 3, 0);
7963      rotation = Bits32(opcode, 5, 4) << 3;
7964
7965      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7966      if (BadReg(d) || BadReg(m))
7967        return false;
7968
7969      break;
7970
7971    case eEncodingA1:
7972      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7973      d = Bits32(opcode, 15, 12);
7974      m = Bits32(opcode, 3, 0);
7975      rotation = Bits32(opcode, 11, 10) << 3;
7976
7977      // if d == 15 || m == 15 then UNPREDICTABLE;
7978      if ((d == 15) || (m == 15))
7979        return false;
7980
7981      break;
7982
7983    default:
7984      return false;
7985    }
7986
7987    uint64_t Rm =
7988        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7989    if (!success)
7990      return false;
7991
7992    // rotated = ROR(R[m], rotation);
7993    uint64_t rotated = ROR(Rm, rotation, &success);
7994    if (!success)
7995      return false;
7996
7997    // R[d] = SignExtend(rotated<15:0>, 32);
7998    RegisterInfo source_reg;
7999    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8000
8001    EmulateInstruction::Context context;
8002    context.type = eContextRegisterLoad;
8003    context.SetRegister(source_reg);
8004
8005    int64_t data = llvm::SignExtend64<16>(rotated);
8006    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8007                               (uint64_t)data))
8008      return false;
8009  }
8010
8011  return true;
8012}
8013
8014// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
8015// writes the result to the destination
8016// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8017// extracting the 8-bit value.
8018bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
8019                                        const ARMEncoding encoding) {
8020#if 0
8021    if ConditionPassed() then
8022        EncodingSpecificOperations();
8023        rotated = ROR(R[m], rotation);
8024        R[d] = ZeroExtend(rotated<7:0>, 32);
8025#endif
8026
8027  bool success = false;
8028
8029  if (ConditionPassed(opcode)) {
8030    uint32_t d;
8031    uint32_t m;
8032    uint32_t rotation;
8033
8034    // EncodingSpecificOperations();
8035    switch (encoding) {
8036    case eEncodingT1:
8037      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8038      d = Bits32(opcode, 2, 0);
8039      m = Bits32(opcode, 5, 3);
8040      rotation = 0;
8041
8042      break;
8043
8044    case eEncodingT2:
8045      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8046      d = Bits32(opcode, 11, 8);
8047      m = Bits32(opcode, 3, 0);
8048      rotation = Bits32(opcode, 5, 4) << 3;
8049
8050      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8051      if (BadReg(d) || BadReg(m))
8052        return false;
8053
8054      break;
8055
8056    case eEncodingA1:
8057      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8058      d = Bits32(opcode, 15, 12);
8059      m = Bits32(opcode, 3, 0);
8060      rotation = Bits32(opcode, 11, 10) << 3;
8061
8062      // if d == 15 || m == 15 then UNPREDICTABLE;
8063      if ((d == 15) || (m == 15))
8064        return false;
8065
8066      break;
8067
8068    default:
8069      return false;
8070    }
8071
8072    uint64_t Rm =
8073        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8074    if (!success)
8075      return false;
8076
8077    // rotated = ROR(R[m], rotation);
8078    uint64_t rotated = ROR(Rm, rotation, &success);
8079    if (!success)
8080      return false;
8081
8082    // R[d] = ZeroExtend(rotated<7:0>, 32);
8083    RegisterInfo source_reg;
8084    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8085
8086    EmulateInstruction::Context context;
8087    context.type = eContextRegisterLoad;
8088    context.SetRegister(source_reg);
8089
8090    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8091                               Bits32(rotated, 7, 0)))
8092      return false;
8093  }
8094  return true;
8095}
8096
8097// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
8098// writes the result to the destination
8099// register.  You can specify a rotation by 0, 8, 16, or 24 bits before
8100// extracting the 16-bit value.
8101bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
8102                                        const ARMEncoding encoding) {
8103#if 0
8104    if ConditionPassed() then
8105        EncodingSpecificOperations();
8106        rotated = ROR(R[m], rotation);
8107        R[d] = ZeroExtend(rotated<15:0>, 32);
8108#endif
8109
8110  bool success = false;
8111
8112  if (ConditionPassed(opcode)) {
8113    uint32_t d;
8114    uint32_t m;
8115    uint32_t rotation;
8116
8117    switch (encoding) {
8118    case eEncodingT1:
8119      // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8120      d = Bits32(opcode, 2, 0);
8121      m = Bits32(opcode, 5, 3);
8122      rotation = 0;
8123
8124      break;
8125
8126    case eEncodingT2:
8127      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8128      d = Bits32(opcode, 11, 8);
8129      m = Bits32(opcode, 3, 0);
8130      rotation = Bits32(opcode, 5, 4) << 3;
8131
8132      // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8133      if (BadReg(d) || BadReg(m))
8134        return false;
8135
8136      break;
8137
8138    case eEncodingA1:
8139      // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8140      d = Bits32(opcode, 15, 12);
8141      m = Bits32(opcode, 3, 0);
8142      rotation = Bits32(opcode, 11, 10) << 3;
8143
8144      // if d == 15 || m == 15 then UNPREDICTABLE;
8145      if ((d == 15) || (m == 15))
8146        return false;
8147
8148      break;
8149
8150    default:
8151      return false;
8152    }
8153
8154    uint64_t Rm =
8155        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8156    if (!success)
8157      return false;
8158
8159    // rotated = ROR(R[m], rotation);
8160    uint64_t rotated = ROR(Rm, rotation, &success);
8161    if (!success)
8162      return false;
8163
8164    // R[d] = ZeroExtend(rotated<15:0>, 32);
8165    RegisterInfo source_reg;
8166    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8167
8168    EmulateInstruction::Context context;
8169    context.type = eContextRegisterLoad;
8170    context.SetRegister(source_reg);
8171
8172    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
8173                               Bits32(rotated, 15, 0)))
8174      return false;
8175  }
8176  return true;
8177}
8178
8179// RFE (Return From Exception) loads the PC and the CPSR from the word at the
8180// specified address and the following
8181// word respectively.
8182bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
8183                                       const ARMEncoding encoding) {
8184#if 0
8185    if ConditionPassed() then
8186        EncodingSpecificOperations();
8187        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8188            UNPREDICTABLE;
8189        else
8190            address = if increment then R[n] else R[n]-8;
8191            if wordhigher then address = address+4;
8192            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8193            BranchWritePC(MemA[address,4]);
8194            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8195#endif
8196
8197  bool success = false;
8198
8199  if (ConditionPassed(opcode)) {
8200    uint32_t n;
8201    bool wback;
8202    bool increment;
8203    bool wordhigher;
8204
8205    // EncodingSpecificOperations();
8206    switch (encoding) {
8207    case eEncodingT1:
8208      // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
8209      // FALSE;
8210      n = Bits32(opcode, 19, 16);
8211      wback = BitIsSet(opcode, 21);
8212      increment = false;
8213      wordhigher = false;
8214
8215      // if n == 15 then UNPREDICTABLE;
8216      if (n == 15)
8217        return false;
8218
8219      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8220      if (InITBlock() && !LastInITBlock())
8221        return false;
8222
8223      break;
8224
8225    case eEncodingT2:
8226      // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8227      n = Bits32(opcode, 19, 16);
8228      wback = BitIsSet(opcode, 21);
8229      increment = true;
8230      wordhigher = false;
8231
8232      // if n == 15 then UNPREDICTABLE;
8233      if (n == 15)
8234        return false;
8235
8236      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8237      if (InITBlock() && !LastInITBlock())
8238        return false;
8239
8240      break;
8241
8242    case eEncodingA1:
8243      // n = UInt(Rn);
8244      n = Bits32(opcode, 19, 16);
8245
8246      // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8247      wback = BitIsSet(opcode, 21);
8248      increment = BitIsSet(opcode, 23);
8249      wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
8250
8251      // if n == 15 then UNPREDICTABLE;
8252      if (n == 15)
8253        return false;
8254
8255      break;
8256
8257    default:
8258      return false;
8259    }
8260
8261    // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
8262    // then
8263    if (!CurrentModeIsPrivileged())
8264      // UNPREDICTABLE;
8265      return false;
8266    else {
8267      uint64_t Rn =
8268          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8269      if (!success)
8270        return false;
8271
8272      addr_t address;
8273      // address = if increment then R[n] else R[n]-8;
8274      if (increment)
8275        address = Rn;
8276      else
8277        address = Rn - 8;
8278
8279      // if wordhigher then address = address+4;
8280      if (wordhigher)
8281        address = address + 4;
8282
8283      // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8284      RegisterInfo base_reg;
8285      GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8286
8287      EmulateInstruction::Context context;
8288      context.type = eContextReturnFromException;
8289      context.SetRegisterPlusOffset(base_reg, address - Rn);
8290
8291      uint64_t data = MemARead(context, address + 4, 4, 0, &success);
8292      if (!success)
8293        return false;
8294
8295      CPSRWriteByInstr(data, 15, true);
8296
8297      // BranchWritePC(MemA[address,4]);
8298      uint64_t data2 = MemARead(context, address, 4, 0, &success);
8299      if (!success)
8300        return false;
8301
8302      BranchWritePC(context, data2);
8303
8304      // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8305      if (wback) {
8306        context.type = eContextAdjustBaseRegister;
8307        if (increment) {
8308          context.SetOffset(8);
8309          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8310                                     Rn + 8))
8311            return false;
8312        } else {
8313          context.SetOffset(-8);
8314          if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
8315                                     Rn - 8))
8316            return false;
8317        }
8318      } // if wback
8319    }
8320  } // if ConditionPassed()
8321  return true;
8322}
8323
8324// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
8325// register value and an immediate value,
8326// and writes the result to the destination register.  It can optionally update
8327// the condition flags based on
8328// the result.
8329bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
8330                                          const ARMEncoding encoding) {
8331#if 0
8332    // ARM pseudo code...
8333    if ConditionPassed() then
8334        EncodingSpecificOperations();
8335        result = R[n] EOR imm32;
8336        if d == 15 then         // Can only occur for ARM encoding
8337            ALUWritePC(result); // setflags is always FALSE here
8338        else
8339            R[d] = result;
8340            if setflags then
8341                APSR.N = result<31>;
8342                APSR.Z = IsZeroBit(result);
8343                APSR.C = carry;
8344                // APSR.V unchanged
8345#endif
8346
8347  bool success = false;
8348
8349  if (ConditionPassed(opcode)) {
8350    uint32_t Rd, Rn;
8351    uint32_t
8352        imm32; // the immediate value to be ORed to the value obtained from Rn
8353    bool setflags;
8354    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8355    switch (encoding) {
8356    case eEncodingT1:
8357      Rd = Bits32(opcode, 11, 8);
8358      Rn = Bits32(opcode, 19, 16);
8359      setflags = BitIsSet(opcode, 20);
8360      imm32 = ThumbExpandImm_C(
8361          opcode, APSR_C,
8362          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8363      // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8364      if (Rd == 15 && setflags)
8365        return EmulateTEQImm(opcode, eEncodingT1);
8366      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8367        return false;
8368      break;
8369    case eEncodingA1:
8370      Rd = Bits32(opcode, 15, 12);
8371      Rn = Bits32(opcode, 19, 16);
8372      setflags = BitIsSet(opcode, 20);
8373      imm32 =
8374          ARMExpandImm_C(opcode, APSR_C,
8375                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8376
8377      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8378      // instructions;
8379      if (Rd == 15 && setflags)
8380        return EmulateSUBSPcLrEtc(opcode, encoding);
8381      break;
8382    default:
8383      return false;
8384    }
8385
8386    // Read the first operand.
8387    uint32_t val1 = ReadCoreReg(Rn, &success);
8388    if (!success)
8389      return false;
8390
8391    uint32_t result = val1 ^ imm32;
8392
8393    EmulateInstruction::Context context;
8394    context.type = EmulateInstruction::eContextImmediate;
8395    context.SetNoArgs();
8396
8397    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8398      return false;
8399  }
8400  return true;
8401}
8402
8403// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register
8404// value and an
8405// optionally-shifted register value, and writes the result to the destination
8406// register.
8407// It can optionally update the condition flags based on the result.
8408bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
8409                                          const ARMEncoding encoding) {
8410#if 0
8411    // ARM pseudo code...
8412    if ConditionPassed() then
8413        EncodingSpecificOperations();
8414        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8415        result = R[n] EOR shifted;
8416        if d == 15 then         // Can only occur for ARM encoding
8417            ALUWritePC(result); // setflags is always FALSE here
8418        else
8419            R[d] = result;
8420            if setflags then
8421                APSR.N = result<31>;
8422                APSR.Z = IsZeroBit(result);
8423                APSR.C = carry;
8424                // APSR.V unchanged
8425#endif
8426
8427  bool success = false;
8428
8429  if (ConditionPassed(opcode)) {
8430    uint32_t Rd, Rn, Rm;
8431    ARM_ShifterType shift_t;
8432    uint32_t shift_n; // the shift applied to the value read from Rm
8433    bool setflags;
8434    uint32_t carry;
8435    switch (encoding) {
8436    case eEncodingT1:
8437      Rd = Rn = Bits32(opcode, 2, 0);
8438      Rm = Bits32(opcode, 5, 3);
8439      setflags = !InITBlock();
8440      shift_t = SRType_LSL;
8441      shift_n = 0;
8442      break;
8443    case eEncodingT2:
8444      Rd = Bits32(opcode, 11, 8);
8445      Rn = Bits32(opcode, 19, 16);
8446      Rm = Bits32(opcode, 3, 0);
8447      setflags = BitIsSet(opcode, 20);
8448      shift_n = DecodeImmShiftThumb(opcode, shift_t);
8449      // if Rd == '1111' && S == '1' then SEE TEQ (register);
8450      if (Rd == 15 && setflags)
8451        return EmulateTEQReg(opcode, eEncodingT1);
8452      if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8453        return false;
8454      break;
8455    case eEncodingA1:
8456      Rd = Bits32(opcode, 15, 12);
8457      Rn = Bits32(opcode, 19, 16);
8458      Rm = Bits32(opcode, 3, 0);
8459      setflags = BitIsSet(opcode, 20);
8460      shift_n = DecodeImmShiftARM(opcode, shift_t);
8461
8462      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8463      // instructions;
8464      if (Rd == 15 && setflags)
8465        return EmulateSUBSPcLrEtc(opcode, encoding);
8466      break;
8467    default:
8468      return false;
8469    }
8470
8471    // Read the first operand.
8472    uint32_t val1 = ReadCoreReg(Rn, &success);
8473    if (!success)
8474      return false;
8475
8476    // Read the second operand.
8477    uint32_t val2 = ReadCoreReg(Rm, &success);
8478    if (!success)
8479      return false;
8480
8481    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8482    if (!success)
8483      return false;
8484    uint32_t result = val1 ^ shifted;
8485
8486    EmulateInstruction::Context context;
8487    context.type = EmulateInstruction::eContextImmediate;
8488    context.SetNoArgs();
8489
8490    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8491      return false;
8492  }
8493  return true;
8494}
8495
8496// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
8497// and an immediate value, and
8498// writes the result to the destination register.  It can optionally update the
8499// condition flags based
8500// on the result.
8501bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
8502                                          const ARMEncoding encoding) {
8503#if 0
8504    // ARM pseudo code...
8505    if ConditionPassed() then
8506        EncodingSpecificOperations();
8507        result = R[n] OR imm32;
8508        if d == 15 then         // Can only occur for ARM encoding
8509            ALUWritePC(result); // setflags is always FALSE here
8510        else
8511            R[d] = result;
8512            if setflags then
8513                APSR.N = result<31>;
8514                APSR.Z = IsZeroBit(result);
8515                APSR.C = carry;
8516                // APSR.V unchanged
8517#endif
8518
8519  bool success = false;
8520
8521  if (ConditionPassed(opcode)) {
8522    uint32_t Rd, Rn;
8523    uint32_t
8524        imm32; // the immediate value to be ORed to the value obtained from Rn
8525    bool setflags;
8526    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8527    switch (encoding) {
8528    case eEncodingT1:
8529      Rd = Bits32(opcode, 11, 8);
8530      Rn = Bits32(opcode, 19, 16);
8531      setflags = BitIsSet(opcode, 20);
8532      imm32 = ThumbExpandImm_C(
8533          opcode, APSR_C,
8534          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8535      // if Rn == '1111' then SEE MOV (immediate);
8536      if (Rn == 15)
8537        return EmulateMOVRdImm(opcode, eEncodingT2);
8538      if (BadReg(Rd) || Rn == 13)
8539        return false;
8540      break;
8541    case eEncodingA1:
8542      Rd = Bits32(opcode, 15, 12);
8543      Rn = Bits32(opcode, 19, 16);
8544      setflags = BitIsSet(opcode, 20);
8545      imm32 =
8546          ARMExpandImm_C(opcode, APSR_C,
8547                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8548
8549      if (Rd == 15 && setflags)
8550        return EmulateSUBSPcLrEtc(opcode, encoding);
8551      break;
8552    default:
8553      return false;
8554    }
8555
8556    // Read the first operand.
8557    uint32_t val1 = ReadCoreReg(Rn, &success);
8558    if (!success)
8559      return false;
8560
8561    uint32_t result = val1 | imm32;
8562
8563    EmulateInstruction::Context context;
8564    context.type = EmulateInstruction::eContextImmediate;
8565    context.SetNoArgs();
8566
8567    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8568      return false;
8569  }
8570  return true;
8571}
8572
8573// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
8574// and an optionally-shifted register
8575// value, and writes the result to the destination register.  It can optionally
8576// update the condition flags based
8577// on the result.
8578bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
8579                                          const ARMEncoding encoding) {
8580#if 0
8581    // ARM pseudo code...
8582    if ConditionPassed() then
8583        EncodingSpecificOperations();
8584        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8585        result = R[n] OR shifted;
8586        if d == 15 then         // Can only occur for ARM encoding
8587            ALUWritePC(result); // setflags is always FALSE here
8588        else
8589            R[d] = result;
8590            if setflags then
8591                APSR.N = result<31>;
8592                APSR.Z = IsZeroBit(result);
8593                APSR.C = carry;
8594                // APSR.V unchanged
8595#endif
8596
8597  bool success = false;
8598
8599  if (ConditionPassed(opcode)) {
8600    uint32_t Rd, Rn, Rm;
8601    ARM_ShifterType shift_t;
8602    uint32_t shift_n; // the shift applied to the value read from Rm
8603    bool setflags;
8604    uint32_t carry;
8605    switch (encoding) {
8606    case eEncodingT1:
8607      Rd = Rn = Bits32(opcode, 2, 0);
8608      Rm = Bits32(opcode, 5, 3);
8609      setflags = !InITBlock();
8610      shift_t = SRType_LSL;
8611      shift_n = 0;
8612      break;
8613    case eEncodingT2:
8614      Rd = Bits32(opcode, 11, 8);
8615      Rn = Bits32(opcode, 19, 16);
8616      Rm = Bits32(opcode, 3, 0);
8617      setflags = BitIsSet(opcode, 20);
8618      shift_n = DecodeImmShiftThumb(opcode, shift_t);
8619      // if Rn == '1111' then SEE MOV (register);
8620      if (Rn == 15)
8621        return EmulateMOVRdRm(opcode, eEncodingT3);
8622      if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8623        return false;
8624      break;
8625    case eEncodingA1:
8626      Rd = Bits32(opcode, 15, 12);
8627      Rn = Bits32(opcode, 19, 16);
8628      Rm = Bits32(opcode, 3, 0);
8629      setflags = BitIsSet(opcode, 20);
8630      shift_n = DecodeImmShiftARM(opcode, shift_t);
8631
8632      if (Rd == 15 && setflags)
8633        return EmulateSUBSPcLrEtc(opcode, encoding);
8634      break;
8635    default:
8636      return false;
8637    }
8638
8639    // Read the first operand.
8640    uint32_t val1 = ReadCoreReg(Rn, &success);
8641    if (!success)
8642      return false;
8643
8644    // Read the second operand.
8645    uint32_t val2 = ReadCoreReg(Rm, &success);
8646    if (!success)
8647      return false;
8648
8649    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8650    if (!success)
8651      return false;
8652    uint32_t result = val1 | shifted;
8653
8654    EmulateInstruction::Context context;
8655    context.type = EmulateInstruction::eContextImmediate;
8656    context.SetNoArgs();
8657
8658    if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8659      return false;
8660  }
8661  return true;
8662}
8663
8664// Reverse Subtract (immediate) subtracts a register value from an immediate
8665// value, and writes the result to
8666// the destination register. It can optionally update the condition flags based
8667// on the result.
8668bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
8669                                          const ARMEncoding encoding) {
8670#if 0
8671    // ARM pseudo code...
8672    if ConditionPassed() then
8673        EncodingSpecificOperations();
8674        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8675        if d == 15 then         // Can only occur for ARM encoding
8676            ALUWritePC(result); // setflags is always FALSE here
8677        else
8678            R[d] = result;
8679            if setflags then
8680                APSR.N = result<31>;
8681                APSR.Z = IsZeroBit(result);
8682                APSR.C = carry;
8683                APSR.V = overflow;
8684#endif
8685
8686  bool success = false;
8687
8688  uint32_t Rd; // the destination register
8689  uint32_t Rn; // the first operand
8690  bool setflags;
8691  uint32_t
8692      imm32; // the immediate value to be added to the value obtained from Rn
8693  switch (encoding) {
8694  case eEncodingT1:
8695    Rd = Bits32(opcode, 2, 0);
8696    Rn = Bits32(opcode, 5, 3);
8697    setflags = !InITBlock();
8698    imm32 = 0;
8699    break;
8700  case eEncodingT2:
8701    Rd = Bits32(opcode, 11, 8);
8702    Rn = Bits32(opcode, 19, 16);
8703    setflags = BitIsSet(opcode, 20);
8704    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8705    if (BadReg(Rd) || BadReg(Rn))
8706      return false;
8707    break;
8708  case eEncodingA1:
8709    Rd = Bits32(opcode, 15, 12);
8710    Rn = Bits32(opcode, 19, 16);
8711    setflags = BitIsSet(opcode, 20);
8712    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8713
8714    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8715    // instructions;
8716    if (Rd == 15 && setflags)
8717      return EmulateSUBSPcLrEtc(opcode, encoding);
8718    break;
8719  default:
8720    return false;
8721  }
8722  // Read the register value from the operand register Rn.
8723  uint32_t reg_val = ReadCoreReg(Rn, &success);
8724  if (!success)
8725    return false;
8726
8727  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8728
8729  EmulateInstruction::Context context;
8730  context.type = EmulateInstruction::eContextImmediate;
8731  context.SetNoArgs();
8732
8733  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
8734                                 res.carry_out, res.overflow))
8735    return false;
8736
8737  return true;
8738}
8739
8740// Reverse Subtract (register) subtracts a register value from an
8741// optionally-shifted register value, and writes the
8742// result to the destination register. It can optionally update the condition
8743// flags based on the result.
8744bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
8745                                          const ARMEncoding encoding) {
8746#if 0
8747    // ARM pseudo code...
8748    if ConditionPassed() then
8749        EncodingSpecificOperations();
8750        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8751        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8752        if d == 15 then         // Can only occur for ARM encoding
8753            ALUWritePC(result); // setflags is always FALSE here
8754        else
8755            R[d] = result;
8756            if setflags then
8757                APSR.N = result<31>;
8758                APSR.Z = IsZeroBit(result);
8759                APSR.C = carry;
8760                APSR.V = overflow;
8761#endif
8762
8763  bool success = false;
8764
8765  uint32_t Rd; // the destination register
8766  uint32_t Rn; // the first operand
8767  uint32_t Rm; // the second operand
8768  bool setflags;
8769  ARM_ShifterType shift_t;
8770  uint32_t shift_n; // the shift applied to the value read from Rm
8771  switch (encoding) {
8772  case eEncodingT1:
8773    Rd = Bits32(opcode, 11, 8);
8774    Rn = Bits32(opcode, 19, 16);
8775    Rm = Bits32(opcode, 3, 0);
8776    setflags = BitIsSet(opcode, 20);
8777    shift_n = DecodeImmShiftThumb(opcode, shift_t);
8778    // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8779    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8780      return false;
8781    break;
8782  case eEncodingA1:
8783    Rd = Bits32(opcode, 15, 12);
8784    Rn = Bits32(opcode, 19, 16);
8785    Rm = Bits32(opcode, 3, 0);
8786    setflags = BitIsSet(opcode, 20);
8787    shift_n = DecodeImmShiftARM(opcode, shift_t);
8788
8789    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8790    // instructions;
8791    if (Rd == 15 && setflags)
8792      return EmulateSUBSPcLrEtc(opcode, encoding);
8793    break;
8794  default:
8795    return false;
8796  }
8797  // Read the register value from register Rn.
8798  uint32_t val1 = ReadCoreReg(Rn, &success);
8799  if (!success)
8800    return false;
8801
8802  // Read the register value from register Rm.
8803  uint32_t val2 = ReadCoreReg(Rm, &success);
8804  if (!success)
8805    return false;
8806
8807  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8808  if (!success)
8809    return false;
8810  AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8811
8812  EmulateInstruction::Context context;
8813  context.type = EmulateInstruction::eContextImmediate;
8814  context.SetNoArgs();
8815  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
8816                                 res.carry_out, res.overflow))
8817    return false;
8818
8819  return true;
8820}
8821
8822// Reverse Subtract with Carry (immediate) subtracts a register value and the
8823// value of NOT (Carry flag) from
8824// an immediate value, and writes the result to the destination register. It can
8825// optionally update the condition
8826// flags based on the result.
8827bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
8828                                          const ARMEncoding encoding) {
8829#if 0
8830    // ARM pseudo code...
8831    if ConditionPassed() then
8832        EncodingSpecificOperations();
8833        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8834        if d == 15 then
8835            ALUWritePC(result); // setflags is always FALSE here
8836        else
8837            R[d] = result;
8838            if setflags then
8839                APSR.N = result<31>;
8840                APSR.Z = IsZeroBit(result);
8841                APSR.C = carry;
8842                APSR.V = overflow;
8843#endif
8844
8845  bool success = false;
8846
8847  uint32_t Rd; // the destination register
8848  uint32_t Rn; // the first operand
8849  bool setflags;
8850  uint32_t
8851      imm32; // the immediate value to be added to the value obtained from Rn
8852  switch (encoding) {
8853  case eEncodingA1:
8854    Rd = Bits32(opcode, 15, 12);
8855    Rn = Bits32(opcode, 19, 16);
8856    setflags = BitIsSet(opcode, 20);
8857    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8858
8859    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8860    // instructions;
8861    if (Rd == 15 && setflags)
8862      return EmulateSUBSPcLrEtc(opcode, encoding);
8863    break;
8864  default:
8865    return false;
8866  }
8867  // Read the register value from the operand register Rn.
8868  uint32_t reg_val = ReadCoreReg(Rn, &success);
8869  if (!success)
8870    return false;
8871
8872  AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8873
8874  EmulateInstruction::Context context;
8875  context.type = EmulateInstruction::eContextImmediate;
8876  context.SetNoArgs();
8877
8878  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
8879                                 res.carry_out, res.overflow))
8880    return false;
8881
8882  return true;
8883}
8884
8885// Reverse Subtract with Carry (register) subtracts a register value and the
8886// value of NOT (Carry flag) from an
8887// optionally-shifted register value, and writes the result to the destination
8888// register. It can optionally update the
8889// condition flags based on the result.
8890bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
8891                                          const ARMEncoding encoding) {
8892#if 0
8893    // ARM pseudo code...
8894    if ConditionPassed() then
8895        EncodingSpecificOperations();
8896        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8897        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8898        if d == 15 then
8899            ALUWritePC(result); // setflags is always FALSE here
8900        else
8901            R[d] = result;
8902            if setflags then
8903                APSR.N = result<31>;
8904                APSR.Z = IsZeroBit(result);
8905                APSR.C = carry;
8906                APSR.V = overflow;
8907#endif
8908
8909  bool success = false;
8910
8911  uint32_t Rd; // the destination register
8912  uint32_t Rn; // the first operand
8913  uint32_t Rm; // the second operand
8914  bool setflags;
8915  ARM_ShifterType shift_t;
8916  uint32_t shift_n; // the shift applied to the value read from Rm
8917  switch (encoding) {
8918  case eEncodingA1:
8919    Rd = Bits32(opcode, 15, 12);
8920    Rn = Bits32(opcode, 19, 16);
8921    Rm = Bits32(opcode, 3, 0);
8922    setflags = BitIsSet(opcode, 20);
8923    shift_n = DecodeImmShiftARM(opcode, shift_t);
8924
8925    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
8926    // instructions;
8927    if (Rd == 15 && setflags)
8928      return EmulateSUBSPcLrEtc(opcode, encoding);
8929    break;
8930  default:
8931    return false;
8932  }
8933  // Read the register value from register Rn.
8934  uint32_t val1 = ReadCoreReg(Rn, &success);
8935  if (!success)
8936    return false;
8937
8938  // Read the register value from register Rm.
8939  uint32_t val2 = ReadCoreReg(Rm, &success);
8940  if (!success)
8941    return false;
8942
8943  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8944  if (!success)
8945    return false;
8946  AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8947
8948  EmulateInstruction::Context context;
8949  context.type = EmulateInstruction::eContextImmediate;
8950  context.SetNoArgs();
8951  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
8952                                 res.carry_out, res.overflow))
8953    return false;
8954
8955  return true;
8956}
8957
8958// Subtract with Carry (immediate) subtracts an immediate value and the value of
8959// NOT (Carry flag) from a register value, and writes the result to the
8960// destination register.
8961// It can optionally update the condition flags based on the result.
8962bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
8963                                          const ARMEncoding encoding) {
8964#if 0
8965    // ARM pseudo code...
8966    if ConditionPassed() then
8967        EncodingSpecificOperations();
8968        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8969        if d == 15 then         // Can only occur for ARM encoding
8970            ALUWritePC(result); // setflags is always FALSE here
8971        else
8972            R[d] = result;
8973            if setflags then
8974                APSR.N = result<31>;
8975                APSR.Z = IsZeroBit(result);
8976                APSR.C = carry;
8977                APSR.V = overflow;
8978#endif
8979
8980  bool success = false;
8981
8982  uint32_t Rd; // the destination register
8983  uint32_t Rn; // the first operand
8984  bool setflags;
8985  uint32_t
8986      imm32; // the immediate value to be added to the value obtained from Rn
8987  switch (encoding) {
8988  case eEncodingT1:
8989    Rd = Bits32(opcode, 11, 8);
8990    Rn = Bits32(opcode, 19, 16);
8991    setflags = BitIsSet(opcode, 20);
8992    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8993    if (BadReg(Rd) || BadReg(Rn))
8994      return false;
8995    break;
8996  case eEncodingA1:
8997    Rd = Bits32(opcode, 15, 12);
8998    Rn = Bits32(opcode, 19, 16);
8999    setflags = BitIsSet(opcode, 20);
9000    imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9001
9002    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9003    // instructions;
9004    if (Rd == 15 && setflags)
9005      return EmulateSUBSPcLrEtc(opcode, encoding);
9006    break;
9007  default:
9008    return false;
9009  }
9010  // Read the register value from the operand register Rn.
9011  uint32_t reg_val = ReadCoreReg(Rn, &success);
9012  if (!success)
9013    return false;
9014
9015  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9016
9017  EmulateInstruction::Context context;
9018  context.type = EmulateInstruction::eContextImmediate;
9019  context.SetNoArgs();
9020
9021  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9022                                 res.carry_out, res.overflow))
9023    return false;
9024
9025  return true;
9026}
9027
9028// Subtract with Carry (register) subtracts an optionally-shifted register value
9029// and the value of
9030// NOT (Carry flag) from a register value, and writes the result to the
9031// destination register.
9032// It can optionally update the condition flags based on the result.
9033bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
9034                                          const ARMEncoding encoding) {
9035#if 0
9036    // ARM pseudo code...
9037    if ConditionPassed() then
9038        EncodingSpecificOperations();
9039        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9040        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9041        if d == 15 then         // Can only occur for ARM encoding
9042            ALUWritePC(result); // setflags is always FALSE here
9043        else
9044            R[d] = result;
9045            if setflags then
9046                APSR.N = result<31>;
9047                APSR.Z = IsZeroBit(result);
9048                APSR.C = carry;
9049                APSR.V = overflow;
9050#endif
9051
9052  bool success = false;
9053
9054  uint32_t Rd; // the destination register
9055  uint32_t Rn; // the first operand
9056  uint32_t Rm; // the second operand
9057  bool setflags;
9058  ARM_ShifterType shift_t;
9059  uint32_t shift_n; // the shift applied to the value read from Rm
9060  switch (encoding) {
9061  case eEncodingT1:
9062    Rd = Rn = Bits32(opcode, 2, 0);
9063    Rm = Bits32(opcode, 5, 3);
9064    setflags = !InITBlock();
9065    shift_t = SRType_LSL;
9066    shift_n = 0;
9067    break;
9068  case eEncodingT2:
9069    Rd = Bits32(opcode, 11, 8);
9070    Rn = Bits32(opcode, 19, 16);
9071    Rm = Bits32(opcode, 3, 0);
9072    setflags = BitIsSet(opcode, 20);
9073    shift_n = DecodeImmShiftThumb(opcode, shift_t);
9074    if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9075      return false;
9076    break;
9077  case eEncodingA1:
9078    Rd = Bits32(opcode, 15, 12);
9079    Rn = Bits32(opcode, 19, 16);
9080    Rm = Bits32(opcode, 3, 0);
9081    setflags = BitIsSet(opcode, 20);
9082    shift_n = DecodeImmShiftARM(opcode, shift_t);
9083
9084    // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9085    // instructions;
9086    if (Rd == 15 && setflags)
9087      return EmulateSUBSPcLrEtc(opcode, encoding);
9088    break;
9089  default:
9090    return false;
9091  }
9092  // Read the register value from register Rn.
9093  uint32_t val1 = ReadCoreReg(Rn, &success);
9094  if (!success)
9095    return false;
9096
9097  // Read the register value from register Rm.
9098  uint32_t val2 = ReadCoreReg(Rm, &success);
9099  if (!success)
9100    return false;
9101
9102  uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9103  if (!success)
9104    return false;
9105  AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9106
9107  EmulateInstruction::Context context;
9108  context.type = EmulateInstruction::eContextImmediate;
9109  context.SetNoArgs();
9110  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9111                                 res.carry_out, res.overflow))
9112    return false;
9113
9114  return true;
9115}
9116
9117// This instruction subtracts an immediate value from a register value, and
9118// writes the result
9119// to the destination register.  It can optionally update the condition flags
9120// based on the result.
9121bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
9122                                               const ARMEncoding encoding) {
9123#if 0
9124    // ARM pseudo code...
9125    if ConditionPassed() then
9126        EncodingSpecificOperations();
9127        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9128        R[d] = result;
9129        if setflags then
9130            APSR.N = result<31>;
9131            APSR.Z = IsZeroBit(result);
9132            APSR.C = carry;
9133            APSR.V = overflow;
9134#endif
9135
9136  bool success = false;
9137
9138  uint32_t Rd; // the destination register
9139  uint32_t Rn; // the first operand
9140  bool setflags;
9141  uint32_t imm32; // the immediate value to be subtracted from the value
9142                  // obtained from Rn
9143  switch (encoding) {
9144  case eEncodingT1:
9145    Rd = Bits32(opcode, 2, 0);
9146    Rn = Bits32(opcode, 5, 3);
9147    setflags = !InITBlock();
9148    imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9149    break;
9150  case eEncodingT2:
9151    Rd = Rn = Bits32(opcode, 10, 8);
9152    setflags = !InITBlock();
9153    imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9154    break;
9155  case eEncodingT3:
9156    Rd = Bits32(opcode, 11, 8);
9157    Rn = Bits32(opcode, 19, 16);
9158    setflags = BitIsSet(opcode, 20);
9159    imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9160
9161    // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9162    if (Rd == 15 && setflags)
9163      return EmulateCMPImm(opcode, eEncodingT2);
9164
9165    // if Rn == '1101' then SEE SUB (SP minus immediate);
9166    if (Rn == 13)
9167      return EmulateSUBSPImm(opcode, eEncodingT2);
9168
9169    // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9170    if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9171      return false;
9172    break;
9173  case eEncodingT4:
9174    Rd = Bits32(opcode, 11, 8);
9175    Rn = Bits32(opcode, 19, 16);
9176    setflags = BitIsSet(opcode, 20);
9177    imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9178
9179    // if Rn == '1111' then SEE ADR;
9180    if (Rn == 15)
9181      return EmulateADR(opcode, eEncodingT2);
9182
9183    // if Rn == '1101' then SEE SUB (SP minus immediate);
9184    if (Rn == 13)
9185      return EmulateSUBSPImm(opcode, eEncodingT3);
9186
9187    if (BadReg(Rd))
9188      return false;
9189    break;
9190  default:
9191    return false;
9192  }
9193  // Read the register value from the operand register Rn.
9194  uint32_t reg_val = ReadCoreReg(Rn, &success);
9195  if (!success)
9196    return false;
9197
9198  AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9199
9200  EmulateInstruction::Context context;
9201  context.type = EmulateInstruction::eContextImmediate;
9202  context.SetNoArgs();
9203
9204  if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9205                                 res.carry_out, res.overflow))
9206    return false;
9207
9208  return true;
9209}
9210
9211// This instruction subtracts an immediate value from a register value, and
9212// writes the result
9213// to the destination register.  It can optionally update the condition flags
9214// based on the result.
9215bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
9216                                             const ARMEncoding encoding) {
9217#if 0
9218    // ARM pseudo code...
9219    if ConditionPassed() then
9220        EncodingSpecificOperations();
9221        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9222        if d == 15 then
9223            ALUWritePC(result); // setflags is always FALSE here
9224        else
9225            R[d] = result;
9226            if setflags then
9227                APSR.N = result<31>;
9228                APSR.Z = IsZeroBit(result);
9229                APSR.C = carry;
9230                APSR.V = overflow;
9231#endif
9232
9233  bool success = false;
9234
9235  if (ConditionPassed(opcode)) {
9236    uint32_t Rd; // the destination register
9237    uint32_t Rn; // the first operand
9238    bool setflags;
9239    uint32_t imm32; // the immediate value to be subtracted from the value
9240                    // obtained from Rn
9241    switch (encoding) {
9242    case eEncodingA1:
9243      Rd = Bits32(opcode, 15, 12);
9244      Rn = Bits32(opcode, 19, 16);
9245      setflags = BitIsSet(opcode, 20);
9246      imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9247
9248      // if Rn == '1111' && S == '0' then SEE ADR;
9249      if (Rn == 15 && !setflags)
9250        return EmulateADR(opcode, eEncodingA2);
9251
9252      // if Rn == '1101' then SEE SUB (SP minus immediate);
9253      if (Rn == 13)
9254        return EmulateSUBSPImm(opcode, eEncodingA1);
9255
9256      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9257      // instructions;
9258      if (Rd == 15 && setflags)
9259        return EmulateSUBSPcLrEtc(opcode, encoding);
9260      break;
9261    default:
9262      return false;
9263    }
9264    // Read the register value from the operand register Rn.
9265    uint32_t reg_val = ReadCoreReg(Rn, &success);
9266    if (!success)
9267      return false;
9268
9269    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9270
9271    EmulateInstruction::Context context;
9272    if (Rd == 13)
9273      context.type = EmulateInstruction::eContextAdjustStackPointer;
9274    else
9275      context.type = EmulateInstruction::eContextRegisterPlusOffset;
9276
9277    RegisterInfo dwarf_reg;
9278    GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
9279    int64_t imm32_signed = imm32;
9280    context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
9281
9282    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
9283                                   res.carry_out, res.overflow))
9284      return false;
9285  }
9286  return true;
9287}
9288
9289// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
9290// register value and an
9291// immediate value.  It updates the condition flags based on the result, and
9292// discards the result.
9293bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
9294                                          const ARMEncoding encoding) {
9295#if 0
9296    // ARM pseudo code...
9297    if ConditionPassed() then
9298        EncodingSpecificOperations();
9299        result = R[n] EOR imm32;
9300        APSR.N = result<31>;
9301        APSR.Z = IsZeroBit(result);
9302        APSR.C = carry;
9303        // APSR.V unchanged
9304#endif
9305
9306  bool success = false;
9307
9308  if (ConditionPassed(opcode)) {
9309    uint32_t Rn;
9310    uint32_t
9311        imm32; // the immediate value to be ANDed to the value obtained from Rn
9312    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9313    switch (encoding) {
9314    case eEncodingT1:
9315      Rn = Bits32(opcode, 19, 16);
9316      imm32 = ThumbExpandImm_C(
9317          opcode, APSR_C,
9318          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9319      if (BadReg(Rn))
9320        return false;
9321      break;
9322    case eEncodingA1:
9323      Rn = Bits32(opcode, 19, 16);
9324      imm32 =
9325          ARMExpandImm_C(opcode, APSR_C,
9326                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9327      break;
9328    default:
9329      return false;
9330    }
9331
9332    // Read the first operand.
9333    uint32_t val1 = ReadCoreReg(Rn, &success);
9334    if (!success)
9335      return false;
9336
9337    uint32_t result = val1 ^ imm32;
9338
9339    EmulateInstruction::Context context;
9340    context.type = EmulateInstruction::eContextImmediate;
9341    context.SetNoArgs();
9342
9343    if (!WriteFlags(context, result, carry))
9344      return false;
9345  }
9346  return true;
9347}
9348
9349// Test Equivalence (register) performs a bitwise exclusive OR operation on a
9350// register value and an
9351// optionally-shifted register value.  It updates the condition flags based on
9352// the result, and discards
9353// the result.
9354bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
9355                                          const ARMEncoding encoding) {
9356#if 0
9357    // ARM pseudo code...
9358    if ConditionPassed() then
9359        EncodingSpecificOperations();
9360        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9361        result = R[n] EOR shifted;
9362        APSR.N = result<31>;
9363        APSR.Z = IsZeroBit(result);
9364        APSR.C = carry;
9365        // APSR.V unchanged
9366#endif
9367
9368  bool success = false;
9369
9370  if (ConditionPassed(opcode)) {
9371    uint32_t Rn, Rm;
9372    ARM_ShifterType shift_t;
9373    uint32_t shift_n; // the shift applied to the value read from Rm
9374    uint32_t carry;
9375    switch (encoding) {
9376    case eEncodingT1:
9377      Rn = Bits32(opcode, 19, 16);
9378      Rm = Bits32(opcode, 3, 0);
9379      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9380      if (BadReg(Rn) || BadReg(Rm))
9381        return false;
9382      break;
9383    case eEncodingA1:
9384      Rn = Bits32(opcode, 19, 16);
9385      Rm = Bits32(opcode, 3, 0);
9386      shift_n = DecodeImmShiftARM(opcode, shift_t);
9387      break;
9388    default:
9389      return false;
9390    }
9391
9392    // Read the first operand.
9393    uint32_t val1 = ReadCoreReg(Rn, &success);
9394    if (!success)
9395      return false;
9396
9397    // Read the second operand.
9398    uint32_t val2 = ReadCoreReg(Rm, &success);
9399    if (!success)
9400      return false;
9401
9402    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9403    if (!success)
9404      return false;
9405    uint32_t result = val1 ^ shifted;
9406
9407    EmulateInstruction::Context context;
9408    context.type = EmulateInstruction::eContextImmediate;
9409    context.SetNoArgs();
9410
9411    if (!WriteFlags(context, result, carry))
9412      return false;
9413  }
9414  return true;
9415}
9416
9417// Test (immediate) performs a bitwise AND operation on a register value and an
9418// immediate value.
9419// It updates the condition flags based on the result, and discards the result.
9420bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
9421                                          const ARMEncoding encoding) {
9422#if 0
9423    // ARM pseudo code...
9424    if ConditionPassed() then
9425        EncodingSpecificOperations();
9426        result = R[n] AND imm32;
9427        APSR.N = result<31>;
9428        APSR.Z = IsZeroBit(result);
9429        APSR.C = carry;
9430        // APSR.V unchanged
9431#endif
9432
9433  bool success = false;
9434
9435  if (ConditionPassed(opcode)) {
9436    uint32_t Rn;
9437    uint32_t
9438        imm32; // the immediate value to be ANDed to the value obtained from Rn
9439    uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9440    switch (encoding) {
9441    case eEncodingT1:
9442      Rn = Bits32(opcode, 19, 16);
9443      imm32 = ThumbExpandImm_C(
9444          opcode, APSR_C,
9445          carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9446      if (BadReg(Rn))
9447        return false;
9448      break;
9449    case eEncodingA1:
9450      Rn = Bits32(opcode, 19, 16);
9451      imm32 =
9452          ARMExpandImm_C(opcode, APSR_C,
9453                         carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9454      break;
9455    default:
9456      return false;
9457    }
9458
9459    // Read the first operand.
9460    uint32_t val1 = ReadCoreReg(Rn, &success);
9461    if (!success)
9462      return false;
9463
9464    uint32_t result = val1 & imm32;
9465
9466    EmulateInstruction::Context context;
9467    context.type = EmulateInstruction::eContextImmediate;
9468    context.SetNoArgs();
9469
9470    if (!WriteFlags(context, result, carry))
9471      return false;
9472  }
9473  return true;
9474}
9475
9476// Test (register) performs a bitwise AND operation on a register value and an
9477// optionally-shifted register value.
9478// It updates the condition flags based on the result, and discards the result.
9479bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
9480                                          const ARMEncoding encoding) {
9481#if 0
9482    // ARM pseudo code...
9483    if ConditionPassed() then
9484        EncodingSpecificOperations();
9485        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9486        result = R[n] AND shifted;
9487        APSR.N = result<31>;
9488        APSR.Z = IsZeroBit(result);
9489        APSR.C = carry;
9490        // APSR.V unchanged
9491#endif
9492
9493  bool success = false;
9494
9495  if (ConditionPassed(opcode)) {
9496    uint32_t Rn, Rm;
9497    ARM_ShifterType shift_t;
9498    uint32_t shift_n; // the shift applied to the value read from Rm
9499    uint32_t carry;
9500    switch (encoding) {
9501    case eEncodingT1:
9502      Rn = Bits32(opcode, 2, 0);
9503      Rm = Bits32(opcode, 5, 3);
9504      shift_t = SRType_LSL;
9505      shift_n = 0;
9506      break;
9507    case eEncodingT2:
9508      Rn = Bits32(opcode, 19, 16);
9509      Rm = Bits32(opcode, 3, 0);
9510      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9511      if (BadReg(Rn) || BadReg(Rm))
9512        return false;
9513      break;
9514    case eEncodingA1:
9515      Rn = Bits32(opcode, 19, 16);
9516      Rm = Bits32(opcode, 3, 0);
9517      shift_n = DecodeImmShiftARM(opcode, shift_t);
9518      break;
9519    default:
9520      return false;
9521    }
9522
9523    // Read the first operand.
9524    uint32_t val1 = ReadCoreReg(Rn, &success);
9525    if (!success)
9526      return false;
9527
9528    // Read the second operand.
9529    uint32_t val2 = ReadCoreReg(Rm, &success);
9530    if (!success)
9531      return false;
9532
9533    uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9534    if (!success)
9535      return false;
9536    uint32_t result = val1 & shifted;
9537
9538    EmulateInstruction::Context context;
9539    context.type = EmulateInstruction::eContextImmediate;
9540    context.SetNoArgs();
9541
9542    if (!WriteFlags(context, result, carry))
9543      return false;
9544  }
9545  return true;
9546}
9547
9548// A8.6.216 SUB (SP minus register)
9549bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
9550                                            const ARMEncoding encoding) {
9551#if 0
9552    if ConditionPassed() then
9553        EncodingSpecificOperations();
9554        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9555        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9556        if d == 15 then // Can only occur for ARM encoding
9557            ALUWritePC(result); // setflags is always FALSE here
9558        else
9559            R[d] = result;
9560            if setflags then
9561                APSR.N = result<31>;
9562                APSR.Z = IsZeroBit(result);
9563                APSR.C = carry;
9564                APSR.V = overflow;
9565#endif
9566
9567  bool success = false;
9568
9569  if (ConditionPassed(opcode)) {
9570    uint32_t d;
9571    uint32_t m;
9572    bool setflags;
9573    ARM_ShifterType shift_t;
9574    uint32_t shift_n;
9575
9576    switch (encoding) {
9577    case eEncodingT1:
9578      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9579      d = Bits32(opcode, 11, 8);
9580      m = Bits32(opcode, 3, 0);
9581      setflags = BitIsSet(opcode, 20);
9582
9583      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9584      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9585
9586      // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
9587      // UNPREDICTABLE;
9588      if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9589        return false;
9590
9591      // if d == 15 || BadReg(m) then UNPREDICTABLE;
9592      if ((d == 15) || BadReg(m))
9593        return false;
9594      break;
9595
9596    case eEncodingA1:
9597      // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9598      d = Bits32(opcode, 15, 12);
9599      m = Bits32(opcode, 3, 0);
9600      setflags = BitIsSet(opcode, 20);
9601
9602      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9603      // instructions;
9604      if (d == 15 && setflags)
9605        EmulateSUBSPcLrEtc(opcode, encoding);
9606
9607      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9608      shift_n = DecodeImmShiftARM(opcode, shift_t);
9609      break;
9610
9611    default:
9612      return false;
9613    }
9614
9615    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9616    uint32_t Rm = ReadCoreReg(m, &success);
9617    if (!success)
9618      return false;
9619
9620    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
9621    if (!success)
9622      return false;
9623
9624    // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9625    uint32_t sp_val = ReadCoreReg(SP_REG, &success);
9626    if (!success)
9627      return false;
9628
9629    AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
9630
9631    EmulateInstruction::Context context;
9632    context.type = eContextArithmetic;
9633    RegisterInfo sp_reg;
9634    GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
9635    RegisterInfo dwarf_reg;
9636    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9637    context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
9638
9639    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
9640                                   res.carry_out, res.overflow))
9641      return false;
9642  }
9643  return true;
9644}
9645
9646// A8.6.7 ADD (register-shifted register)
9647bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
9648                                               const ARMEncoding encoding) {
9649#if 0
9650    if ConditionPassed() then
9651        EncodingSpecificOperations();
9652        shift_n = UInt(R[s]<7:0>);
9653        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9654        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9655        R[d] = result;
9656        if setflags then
9657            APSR.N = result<31>;
9658            APSR.Z = IsZeroBit(result);
9659            APSR.C = carry;
9660            APSR.V = overflow;
9661#endif
9662
9663  bool success = false;
9664
9665  if (ConditionPassed(opcode)) {
9666    uint32_t d;
9667    uint32_t n;
9668    uint32_t m;
9669    uint32_t s;
9670    bool setflags;
9671    ARM_ShifterType shift_t;
9672
9673    switch (encoding) {
9674    case eEncodingA1:
9675      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9676      d = Bits32(opcode, 15, 12);
9677      n = Bits32(opcode, 19, 16);
9678      m = Bits32(opcode, 3, 0);
9679      s = Bits32(opcode, 11, 8);
9680
9681      // setflags = (S == '1'); shift_t = DecodeRegShift(type);
9682      setflags = BitIsSet(opcode, 20);
9683      shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
9684
9685      // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9686      if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9687        return false;
9688      break;
9689
9690    default:
9691      return false;
9692    }
9693
9694    // shift_n = UInt(R[s]<7:0>);
9695    uint32_t Rs = ReadCoreReg(s, &success);
9696    if (!success)
9697      return false;
9698
9699    uint32_t shift_n = Bits32(Rs, 7, 0);
9700
9701    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9702    uint32_t Rm = ReadCoreReg(m, &success);
9703    if (!success)
9704      return false;
9705
9706    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
9707    if (!success)
9708      return false;
9709
9710    // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9711    uint32_t Rn = ReadCoreReg(n, &success);
9712    if (!success)
9713      return false;
9714
9715    AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
9716
9717    // R[d] = result;
9718    EmulateInstruction::Context context;
9719    context.type = eContextArithmetic;
9720    RegisterInfo reg_n;
9721    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9722    RegisterInfo reg_m;
9723    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9724
9725    context.SetRegisterRegisterOperands(reg_n, reg_m);
9726
9727    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
9728                               res.result))
9729      return false;
9730
9731    // if setflags then
9732    // APSR.N = result<31>;
9733    // APSR.Z = IsZeroBit(result);
9734    // APSR.C = carry;
9735    // APSR.V = overflow;
9736    if (setflags)
9737      return WriteFlags(context, res.result, res.carry_out, res.overflow);
9738  }
9739  return true;
9740}
9741
9742// A8.6.213 SUB (register)
9743bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
9744                                          const ARMEncoding encoding) {
9745#if 0
9746    if ConditionPassed() then
9747        EncodingSpecificOperations();
9748        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9749        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9750        if d == 15 then // Can only occur for ARM encoding
9751            ALUWritePC(result); // setflags is always FALSE here
9752        else
9753            R[d] = result;
9754            if setflags then
9755                APSR.N = result<31>;
9756                APSR.Z = IsZeroBit(result);
9757                APSR.C = carry;
9758                APSR.V = overflow;
9759#endif
9760
9761  bool success = false;
9762
9763  if (ConditionPassed(opcode)) {
9764    uint32_t d;
9765    uint32_t n;
9766    uint32_t m;
9767    bool setflags;
9768    ARM_ShifterType shift_t;
9769    uint32_t shift_n;
9770
9771    switch (encoding) {
9772    case eEncodingT1:
9773      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9774      d = Bits32(opcode, 2, 0);
9775      n = Bits32(opcode, 5, 3);
9776      m = Bits32(opcode, 8, 6);
9777      setflags = !InITBlock();
9778
9779      // (shift_t, shift_n) = (SRType_LSL, 0);
9780      shift_t = SRType_LSL;
9781      shift_n = 0;
9782
9783      break;
9784
9785    case eEncodingT2:
9786      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
9787      d = Bits32(opcode, 11, 8);
9788      n = Bits32(opcode, 19, 16);
9789      m = Bits32(opcode, 3, 0);
9790      setflags = BitIsSet(opcode, 20);
9791
9792      // if Rd == "1111" && S == "1" then SEE CMP (register);
9793      if (d == 15 && setflags == 1)
9794        return EmulateCMPImm(opcode, eEncodingT3);
9795
9796      // if Rn == "1101" then SEE SUB (SP minus register);
9797      if (n == 13)
9798        return EmulateSUBSPReg(opcode, eEncodingT1);
9799
9800      // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9801      shift_n = DecodeImmShiftThumb(opcode, shift_t);
9802
9803      // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
9804      // UNPREDICTABLE;
9805      if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
9806          BadReg(m))
9807        return false;
9808
9809      break;
9810
9811    case eEncodingA1:
9812      // if Rn == '1101' then SEE SUB (SP minus register);
9813      // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
9814      d = Bits32(opcode, 15, 12);
9815      n = Bits32(opcode, 19, 16);
9816      m = Bits32(opcode, 3, 0);
9817      setflags = BitIsSet(opcode, 20);
9818
9819      // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
9820      // instructions;
9821      if ((d == 15) && setflags)
9822        EmulateSUBSPcLrEtc(opcode, encoding);
9823
9824      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9825      shift_n = DecodeImmShiftARM(opcode, shift_t);
9826
9827      break;
9828
9829    default:
9830      return false;
9831    }
9832
9833    // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9834    uint32_t Rm = ReadCoreReg(m, &success);
9835    if (!success)
9836      return false;
9837
9838    uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
9839    if (!success)
9840      return false;
9841
9842    // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9843    uint32_t Rn = ReadCoreReg(n, &success);
9844    if (!success)
9845      return false;
9846
9847    AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
9848
9849    // if d == 15 then // Can only occur for ARM encoding
9850    // ALUWritePC(result); // setflags is always FALSE here
9851    // else
9852    // R[d] = result;
9853    // if setflags then
9854    // APSR.N = result<31>;
9855    // APSR.Z = IsZeroBit(result);
9856    // APSR.C = carry;
9857    // APSR.V = overflow;
9858
9859    EmulateInstruction::Context context;
9860    context.type = eContextArithmetic;
9861    RegisterInfo reg_n;
9862    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9863    RegisterInfo reg_m;
9864    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9865    context.SetRegisterRegisterOperands(reg_n, reg_m);
9866
9867    if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
9868                                   res.carry_out, res.overflow))
9869      return false;
9870  }
9871  return true;
9872}
9873
9874// A8.6.202 STREX
9875// Store Register Exclusive calculates an address from a base register value and
9876// an immediate offset, and stores a
9877// word from a register to memory if the executing processor has exclusive
9878// access to the memory addressed.
9879bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
9880                                         const ARMEncoding encoding) {
9881#if 0
9882    if ConditionPassed() then
9883        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9884        address = R[n] + imm32;
9885        if ExclusiveMonitorsPass(address,4) then
9886            MemA[address,4] = R[t];
9887            R[d] = 0;
9888        else
9889            R[d] = 1;
9890#endif
9891
9892  bool success = false;
9893
9894  if (ConditionPassed(opcode)) {
9895    uint32_t d;
9896    uint32_t t;
9897    uint32_t n;
9898    uint32_t imm32;
9899    const uint32_t addr_byte_size = GetAddressByteSize();
9900
9901    switch (encoding) {
9902    case eEncodingT1:
9903      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00',
9904      // 32);
9905      d = Bits32(opcode, 11, 8);
9906      t = Bits32(opcode, 15, 12);
9907      n = Bits32(opcode, 19, 16);
9908      imm32 = Bits32(opcode, 7, 0) << 2;
9909
9910      // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9911      if (BadReg(d) || BadReg(t) || (n == 15))
9912        return false;
9913
9914      // if d == n || d == t then UNPREDICTABLE;
9915      if ((d == n) || (d == t))
9916        return false;
9917
9918      break;
9919
9920    case eEncodingA1:
9921      // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
9922      // offset
9923      d = Bits32(opcode, 15, 12);
9924      t = Bits32(opcode, 3, 0);
9925      n = Bits32(opcode, 19, 16);
9926      imm32 = 0;
9927
9928      // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9929      if ((d == 15) || (t == 15) || (n == 15))
9930        return false;
9931
9932      // if d == n || d == t then UNPREDICTABLE;
9933      if ((d == n) || (d == t))
9934        return false;
9935
9936      break;
9937
9938    default:
9939      return false;
9940    }
9941
9942    // address = R[n] + imm32;
9943    uint32_t Rn = ReadCoreReg(n, &success);
9944    if (!success)
9945      return false;
9946
9947    addr_t address = Rn + imm32;
9948
9949    RegisterInfo base_reg;
9950    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9951    RegisterInfo data_reg;
9952    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9953    EmulateInstruction::Context context;
9954    context.type = eContextRegisterStore;
9955    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
9956
9957    // if ExclusiveMonitorsPass(address,4) then
9958    // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the
9959    // sake of emulation, we will say this
9960    //                                                         always return
9961    //                                                         true.
9962    if (true) {
9963      // MemA[address,4] = R[t];
9964      uint32_t Rt =
9965          ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9966      if (!success)
9967        return false;
9968
9969      if (!MemAWrite(context, address, Rt, addr_byte_size))
9970        return false;
9971
9972      // R[d] = 0;
9973      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9974        return false;
9975    }
9976#if 0  // unreachable because if true
9977        else
9978        {
9979            // R[d] = 1;
9980            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9981                return false;
9982        }
9983#endif // unreachable because if true
9984  }
9985  return true;
9986}
9987
9988// A8.6.197 STRB (immediate, ARM)
9989bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
9990                                              const ARMEncoding encoding) {
9991#if 0
9992    if ConditionPassed() then
9993        EncodingSpecificOperations();
9994        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9995        address = if index then offset_addr else R[n];
9996        MemU[address,1] = R[t]<7:0>;
9997        if wback then R[n] = offset_addr;
9998#endif
9999
10000  bool success = false;
10001
10002  if (ConditionPassed(opcode)) {
10003    uint32_t t;
10004    uint32_t n;
10005    uint32_t imm32;
10006    bool index;
10007    bool add;
10008    bool wback;
10009
10010    switch (encoding) {
10011    case eEncodingA1:
10012      // if P == '0' && W == '1' then SEE STRBT;
10013      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10014      t = Bits32(opcode, 15, 12);
10015      n = Bits32(opcode, 19, 16);
10016      imm32 = Bits32(opcode, 11, 0);
10017
10018      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10019      index = BitIsSet(opcode, 24);
10020      add = BitIsSet(opcode, 23);
10021      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10022
10023      // if t == 15 then UNPREDICTABLE;
10024      if (t == 15)
10025        return false;
10026
10027      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10028      if (wback && ((n == 15) || (n == t)))
10029        return false;
10030
10031      break;
10032
10033    default:
10034      return false;
10035    }
10036
10037    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10038    uint32_t Rn = ReadCoreReg(n, &success);
10039    if (!success)
10040      return false;
10041
10042    addr_t offset_addr;
10043    if (add)
10044      offset_addr = Rn + imm32;
10045    else
10046      offset_addr = Rn - imm32;
10047
10048    // address = if index then offset_addr else R[n];
10049    addr_t address;
10050    if (index)
10051      address = offset_addr;
10052    else
10053      address = Rn;
10054
10055    // MemU[address,1] = R[t]<7:0>;
10056    uint32_t Rt = ReadCoreReg(t, &success);
10057    if (!success)
10058      return false;
10059
10060    RegisterInfo base_reg;
10061    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10062    RegisterInfo data_reg;
10063    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10064    EmulateInstruction::Context context;
10065    context.type = eContextRegisterStore;
10066    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10067
10068    if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
10069      return false;
10070
10071    // if wback then R[n] = offset_addr;
10072    if (wback) {
10073      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10074                                 offset_addr))
10075        return false;
10076    }
10077  }
10078  return true;
10079}
10080
10081// A8.6.194 STR (immediate, ARM)
10082bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
10083                                             const ARMEncoding encoding) {
10084#if 0
10085    if ConditionPassed() then
10086        EncodingSpecificOperations();
10087        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10088        address = if index then offset_addr else R[n];
10089        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10090        if wback then R[n] = offset_addr;
10091#endif
10092
10093  bool success = false;
10094
10095  if (ConditionPassed(opcode)) {
10096    uint32_t t;
10097    uint32_t n;
10098    uint32_t imm32;
10099    bool index;
10100    bool add;
10101    bool wback;
10102
10103    const uint32_t addr_byte_size = GetAddressByteSize();
10104
10105    switch (encoding) {
10106    case eEncodingA1:
10107      // if P == '0' && W == '1' then SEE STRT;
10108      // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
10109      // '000000000100' then SEE PUSH;
10110      // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10111      t = Bits32(opcode, 15, 12);
10112      n = Bits32(opcode, 19, 16);
10113      imm32 = Bits32(opcode, 11, 0);
10114
10115      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10116      index = BitIsSet(opcode, 24);
10117      add = BitIsSet(opcode, 23);
10118      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10119
10120      // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10121      if (wback && ((n == 15) || (n == t)))
10122        return false;
10123
10124      break;
10125
10126    default:
10127      return false;
10128    }
10129
10130    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10131    uint32_t Rn = ReadCoreReg(n, &success);
10132    if (!success)
10133      return false;
10134
10135    addr_t offset_addr;
10136    if (add)
10137      offset_addr = Rn + imm32;
10138    else
10139      offset_addr = Rn - imm32;
10140
10141    // address = if index then offset_addr else R[n];
10142    addr_t address;
10143    if (index)
10144      address = offset_addr;
10145    else
10146      address = Rn;
10147
10148    RegisterInfo base_reg;
10149    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10150    RegisterInfo data_reg;
10151    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10152    EmulateInstruction::Context context;
10153    context.type = eContextRegisterStore;
10154    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10155
10156    // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10157    uint32_t Rt = ReadCoreReg(t, &success);
10158    if (!success)
10159      return false;
10160
10161    if (t == 15) {
10162      uint32_t pc_value = ReadCoreReg(PC_REG, &success);
10163      if (!success)
10164        return false;
10165
10166      if (!MemUWrite(context, address, pc_value, addr_byte_size))
10167        return false;
10168    } else {
10169      if (!MemUWrite(context, address, Rt, addr_byte_size))
10170        return false;
10171    }
10172
10173    // if wback then R[n] = offset_addr;
10174    if (wback) {
10175      context.type = eContextAdjustBaseRegister;
10176      context.SetImmediate(offset_addr);
10177
10178      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10179                                 offset_addr))
10180        return false;
10181    }
10182  }
10183  return true;
10184}
10185
10186// A8.6.66 LDRD (immediate)
10187// Load Register Dual (immediate) calculates an address from a base register
10188// value and an immediate offset, loads two
10189// words from memory, and writes them to two registers.  It can use offset,
10190// post-indexed, or pre-indexed addressing.
10191bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
10192                                                 const ARMEncoding encoding) {
10193#if 0
10194    if ConditionPassed() then
10195        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10196        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10197        address = if index then offset_addr else R[n];
10198        R[t] = MemA[address,4];
10199        R[t2] = MemA[address+4,4];
10200        if wback then R[n] = offset_addr;
10201#endif
10202
10203  bool success = false;
10204
10205  if (ConditionPassed(opcode)) {
10206    uint32_t t;
10207    uint32_t t2;
10208    uint32_t n;
10209    uint32_t imm32;
10210    bool index;
10211    bool add;
10212    bool wback;
10213
10214    switch (encoding) {
10215    case eEncodingT1:
10216      // if P == '0' && W == '0' then SEE 'Related encodings';
10217      // if Rn == '1111' then SEE LDRD (literal);
10218      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10219      // ZeroExtend(imm8:'00', 32);
10220      t = Bits32(opcode, 15, 12);
10221      t2 = Bits32(opcode, 11, 8);
10222      n = Bits32(opcode, 19, 16);
10223      imm32 = Bits32(opcode, 7, 0) << 2;
10224
10225      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10226      index = BitIsSet(opcode, 24);
10227      add = BitIsSet(opcode, 23);
10228      wback = BitIsSet(opcode, 21);
10229
10230      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10231      if (wback && ((n == t) || (n == t2)))
10232        return false;
10233
10234      // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10235      if (BadReg(t) || BadReg(t2) || (t == t2))
10236        return false;
10237
10238      break;
10239
10240    case eEncodingA1:
10241      // if Rn == '1111' then SEE LDRD (literal);
10242      // if Rt<0> == '1' then UNPREDICTABLE;
10243      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10244      // 32);
10245      t = Bits32(opcode, 15, 12);
10246      if (BitIsSet(t, 0))
10247        return false;
10248      t2 = t + 1;
10249      n = Bits32(opcode, 19, 16);
10250      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10251
10252      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10253      index = BitIsSet(opcode, 24);
10254      add = BitIsSet(opcode, 23);
10255      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10256
10257      // if P == '0' && W == '1' then UNPREDICTABLE;
10258      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10259        return false;
10260
10261      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10262      if (wback && ((n == t) || (n == t2)))
10263        return false;
10264
10265      // if t2 == 15 then UNPREDICTABLE;
10266      if (t2 == 15)
10267        return false;
10268
10269      break;
10270
10271    default:
10272      return false;
10273    }
10274
10275    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10276    uint32_t Rn = ReadCoreReg(n, &success);
10277    if (!success)
10278      return false;
10279
10280    addr_t offset_addr;
10281    if (add)
10282      offset_addr = Rn + imm32;
10283    else
10284      offset_addr = Rn - imm32;
10285
10286    // address = if index then offset_addr else R[n];
10287    addr_t address;
10288    if (index)
10289      address = offset_addr;
10290    else
10291      address = Rn;
10292
10293    // R[t] = MemA[address,4];
10294    RegisterInfo base_reg;
10295    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10296
10297    EmulateInstruction::Context context;
10298    if (n == 13)
10299      context.type = eContextPopRegisterOffStack;
10300    else
10301      context.type = eContextRegisterLoad;
10302    context.SetAddress(address);
10303
10304    const uint32_t addr_byte_size = GetAddressByteSize();
10305    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10306    if (!success)
10307      return false;
10308
10309    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10310      return false;
10311
10312    // R[t2] = MemA[address+4,4];
10313    context.SetAddress(address + 4);
10314    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10315    if (!success)
10316      return false;
10317
10318    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10319                               data))
10320      return false;
10321
10322    // if wback then R[n] = offset_addr;
10323    if (wback) {
10324      context.type = eContextAdjustBaseRegister;
10325      context.SetAddress(offset_addr);
10326
10327      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10328                                 offset_addr))
10329        return false;
10330    }
10331  }
10332  return true;
10333}
10334
10335// A8.6.68 LDRD (register)
10336// Load Register Dual (register) calculates an address from a base register
10337// value and a register offset, loads two
10338// words from memory, and writes them to two registers.  It can use offset,
10339// post-indexed or pre-indexed addressing.
10340bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
10341                                                const ARMEncoding encoding) {
10342#if 0
10343    if ConditionPassed() then
10344        EncodingSpecificOperations();
10345        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10346        address = if index then offset_addr else R[n];
10347        R[t] = MemA[address,4];
10348        R[t2] = MemA[address+4,4];
10349        if wback then R[n] = offset_addr;
10350#endif
10351
10352  bool success = false;
10353
10354  if (ConditionPassed(opcode)) {
10355    uint32_t t;
10356    uint32_t t2;
10357    uint32_t n;
10358    uint32_t m;
10359    bool index;
10360    bool add;
10361    bool wback;
10362
10363    switch (encoding) {
10364    case eEncodingA1:
10365      // if Rt<0> == '1' then UNPREDICTABLE;
10366      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10367      t = Bits32(opcode, 15, 12);
10368      if (BitIsSet(t, 0))
10369        return false;
10370      t2 = t + 1;
10371      n = Bits32(opcode, 19, 16);
10372      m = Bits32(opcode, 3, 0);
10373
10374      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10375      index = BitIsSet(opcode, 24);
10376      add = BitIsSet(opcode, 23);
10377      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10378
10379      // if P == '0' && W == '1' then UNPREDICTABLE;
10380      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10381        return false;
10382
10383      // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10384      if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10385        return false;
10386
10387      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10388      if (wback && ((n == 15) || (n == t) || (n == t2)))
10389        return false;
10390
10391      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10392      if ((ArchVersion() < 6) && wback && (m == n))
10393        return false;
10394      break;
10395
10396    default:
10397      return false;
10398    }
10399
10400    uint32_t Rn = ReadCoreReg(n, &success);
10401    if (!success)
10402      return false;
10403    RegisterInfo base_reg;
10404    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10405
10406    uint32_t Rm = ReadCoreReg(m, &success);
10407    if (!success)
10408      return false;
10409    RegisterInfo offset_reg;
10410    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10411
10412    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10413    addr_t offset_addr;
10414    if (add)
10415      offset_addr = Rn + Rm;
10416    else
10417      offset_addr = Rn - Rm;
10418
10419    // address = if index then offset_addr else R[n];
10420    addr_t address;
10421    if (index)
10422      address = offset_addr;
10423    else
10424      address = Rn;
10425
10426    EmulateInstruction::Context context;
10427    if (n == 13)
10428      context.type = eContextPopRegisterOffStack;
10429    else
10430      context.type = eContextRegisterLoad;
10431    context.SetAddress(address);
10432
10433    // R[t] = MemA[address,4];
10434    const uint32_t addr_byte_size = GetAddressByteSize();
10435    uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10436    if (!success)
10437      return false;
10438
10439    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
10440      return false;
10441
10442    // R[t2] = MemA[address+4,4];
10443
10444    data = MemARead(context, address + 4, addr_byte_size, 0, &success);
10445    if (!success)
10446      return false;
10447
10448    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
10449                               data))
10450      return false;
10451
10452    // if wback then R[n] = offset_addr;
10453    if (wback) {
10454      context.type = eContextAdjustBaseRegister;
10455      context.SetAddress(offset_addr);
10456
10457      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10458                                 offset_addr))
10459        return false;
10460    }
10461  }
10462  return true;
10463}
10464
10465// A8.6.200 STRD (immediate)
10466// Store Register Dual (immediate) calculates an address from a base register
10467// value and an immediate offset, and
10468// stores two words from two registers to memory.  It can use offset,
10469// post-indexed, or pre-indexed addressing.
10470bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
10471                                           const ARMEncoding encoding) {
10472#if 0
10473    if ConditionPassed() then
10474        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10475        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10476        address = if index then offset_addr else R[n];
10477        MemA[address,4] = R[t];
10478        MemA[address+4,4] = R[t2];
10479        if wback then R[n] = offset_addr;
10480#endif
10481
10482  bool success = false;
10483
10484  if (ConditionPassed(opcode)) {
10485    uint32_t t;
10486    uint32_t t2;
10487    uint32_t n;
10488    uint32_t imm32;
10489    bool index;
10490    bool add;
10491    bool wback;
10492
10493    switch (encoding) {
10494    case eEncodingT1:
10495      // if P == '0' && W == '0' then SEE 'Related encodings';
10496      // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
10497      // ZeroExtend(imm8:'00', 32);
10498      t = Bits32(opcode, 15, 12);
10499      t2 = Bits32(opcode, 11, 8);
10500      n = Bits32(opcode, 19, 16);
10501      imm32 = Bits32(opcode, 7, 0) << 2;
10502
10503      // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10504      index = BitIsSet(opcode, 24);
10505      add = BitIsSet(opcode, 23);
10506      wback = BitIsSet(opcode, 21);
10507
10508      // if wback && (n == t || n == t2) then UNPREDICTABLE;
10509      if (wback && ((n == t) || (n == t2)))
10510        return false;
10511
10512      // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10513      if ((n == 15) || BadReg(t) || BadReg(t2))
10514        return false;
10515
10516      break;
10517
10518    case eEncodingA1:
10519      // if Rt<0> == '1' then UNPREDICTABLE;
10520      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
10521      // 32);
10522      t = Bits32(opcode, 15, 12);
10523      if (BitIsSet(t, 0))
10524        return false;
10525
10526      t2 = t + 1;
10527      n = Bits32(opcode, 19, 16);
10528      imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
10529
10530      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10531      index = BitIsSet(opcode, 24);
10532      add = BitIsSet(opcode, 23);
10533      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10534
10535      // if P == '0' && W == '1' then UNPREDICTABLE;
10536      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10537        return false;
10538
10539      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10540      if (wback && ((n == 15) || (n == t) || (n == t2)))
10541        return false;
10542
10543      // if t2 == 15 then UNPREDICTABLE;
10544      if (t2 == 15)
10545        return false;
10546
10547      break;
10548
10549    default:
10550      return false;
10551    }
10552
10553    RegisterInfo base_reg;
10554    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10555
10556    uint32_t Rn = ReadCoreReg(n, &success);
10557    if (!success)
10558      return false;
10559
10560    // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10561    addr_t offset_addr;
10562    if (add)
10563      offset_addr = Rn + imm32;
10564    else
10565      offset_addr = Rn - imm32;
10566
10567    // address = if index then offset_addr else R[n];
10568    addr_t address;
10569    if (index)
10570      address = offset_addr;
10571    else
10572      address = Rn;
10573
10574    // MemA[address,4] = R[t];
10575    RegisterInfo data_reg;
10576    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10577
10578    uint32_t data = ReadCoreReg(t, &success);
10579    if (!success)
10580      return false;
10581
10582    EmulateInstruction::Context context;
10583    if (n == 13)
10584      context.type = eContextPushRegisterOnStack;
10585    else
10586      context.type = eContextRegisterStore;
10587    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
10588
10589    const uint32_t addr_byte_size = GetAddressByteSize();
10590
10591    if (!MemAWrite(context, address, data, addr_byte_size))
10592      return false;
10593
10594    // MemA[address+4,4] = R[t2];
10595    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10596    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
10597                                            (address + 4) - Rn);
10598
10599    data = ReadCoreReg(t2, &success);
10600    if (!success)
10601      return false;
10602
10603    if (!MemAWrite(context, address + 4, data, addr_byte_size))
10604      return false;
10605
10606    // if wback then R[n] = offset_addr;
10607    if (wback) {
10608      if (n == 13)
10609        context.type = eContextAdjustStackPointer;
10610      else
10611        context.type = eContextAdjustBaseRegister;
10612      context.SetAddress(offset_addr);
10613
10614      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10615                                 offset_addr))
10616        return false;
10617    }
10618  }
10619  return true;
10620}
10621
10622// A8.6.201 STRD (register)
10623bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
10624                                           const ARMEncoding encoding) {
10625#if 0
10626    if ConditionPassed() then
10627        EncodingSpecificOperations();
10628        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10629        address = if index then offset_addr else R[n];
10630        MemA[address,4] = R[t];
10631        MemA[address+4,4] = R[t2];
10632        if wback then R[n] = offset_addr;
10633#endif
10634
10635  bool success = false;
10636
10637  if (ConditionPassed(opcode)) {
10638    uint32_t t;
10639    uint32_t t2;
10640    uint32_t n;
10641    uint32_t m;
10642    bool index;
10643    bool add;
10644    bool wback;
10645
10646    switch (encoding) {
10647    case eEncodingA1:
10648      // if Rt<0> == '1' then UNPREDICTABLE;
10649      // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10650      t = Bits32(opcode, 15, 12);
10651      if (BitIsSet(t, 0))
10652        return false;
10653
10654      t2 = t + 1;
10655      n = Bits32(opcode, 19, 16);
10656      m = Bits32(opcode, 3, 0);
10657
10658      // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10659      index = BitIsSet(opcode, 24);
10660      add = BitIsSet(opcode, 23);
10661      wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
10662
10663      // if P == '0' && W == '1' then UNPREDICTABLE;
10664      if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
10665        return false;
10666
10667      // if t2 == 15 || m == 15 then UNPREDICTABLE;
10668      if ((t2 == 15) || (m == 15))
10669        return false;
10670
10671      // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10672      if (wback && ((n == 15) || (n == t) || (n == t2)))
10673        return false;
10674
10675      // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10676      if ((ArchVersion() < 6) && wback && (m == n))
10677        return false;
10678
10679      break;
10680
10681    default:
10682      return false;
10683    }
10684
10685    RegisterInfo base_reg;
10686    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10687    RegisterInfo offset_reg;
10688    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10689    RegisterInfo data_reg;
10690
10691    uint32_t Rn = ReadCoreReg(n, &success);
10692    if (!success)
10693      return false;
10694
10695    uint32_t Rm = ReadCoreReg(m, &success);
10696    if (!success)
10697      return false;
10698
10699    // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10700    addr_t offset_addr;
10701    if (add)
10702      offset_addr = Rn + Rm;
10703    else
10704      offset_addr = Rn - Rm;
10705
10706    // address = if index then offset_addr else R[n];
10707    addr_t address;
10708    if (index)
10709      address = offset_addr;
10710    else
10711      address = Rn;
10712    // MemA[address,4] = R[t];
10713    uint32_t Rt = ReadCoreReg(t, &success);
10714    if (!success)
10715      return false;
10716
10717    EmulateInstruction::Context context;
10718    if (t == 13)
10719      context.type = eContextPushRegisterOnStack;
10720    else
10721      context.type = eContextRegisterStore;
10722
10723    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10724    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
10725                                                    data_reg);
10726
10727    const uint32_t addr_byte_size = GetAddressByteSize();
10728
10729    if (!MemAWrite(context, address, Rt, addr_byte_size))
10730      return false;
10731
10732    // MemA[address+4,4] = R[t2];
10733    uint32_t Rt2 = ReadCoreReg(t2, &success);
10734    if (!success)
10735      return false;
10736
10737    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10738
10739    context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
10740                                                    data_reg);
10741
10742    if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
10743      return false;
10744
10745    // if wback then R[n] = offset_addr;
10746    if (wback) {
10747      context.type = eContextAdjustBaseRegister;
10748      context.SetAddress(offset_addr);
10749
10750      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10751                                 offset_addr))
10752        return false;
10753    }
10754  }
10755  return true;
10756}
10757
10758// A8.6.319 VLDM
10759// Vector Load Multiple loads multiple extension registers from consecutive
10760// memory locations using an address from
10761// an ARM core register.
10762bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
10763                                        const ARMEncoding encoding) {
10764#if 0
10765    if ConditionPassed() then
10766        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10767        address = if add then R[n] else R[n]-imm32;
10768        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10769        for r = 0 to regs-1
10770            if single_regs then
10771                S[d+r] = MemA[address,4]; address = address+4;
10772            else
10773                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10774                // Combine the word-aligned words in the correct order for current endianness.
10775                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10776#endif
10777
10778  bool success = false;
10779
10780  if (ConditionPassed(opcode)) {
10781    bool single_regs;
10782    bool add;
10783    bool wback;
10784    uint32_t d;
10785    uint32_t n;
10786    uint32_t imm32;
10787    uint32_t regs;
10788
10789    switch (encoding) {
10790    case eEncodingT1:
10791    case eEncodingA1:
10792      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10793      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10794      // if P == '1' && W == '0' then SEE VLDR;
10795      // if P == U && W == '1' then UNDEFINED;
10796      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
10797        return false;
10798
10799      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
10800      // !), 101 (DB with !)
10801      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
10802      single_regs = false;
10803      add = BitIsSet(opcode, 23);
10804      wback = BitIsSet(opcode, 21);
10805
10806      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10807      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
10808      n = Bits32(opcode, 19, 16);
10809      imm32 = Bits32(opcode, 7, 0) << 2;
10810
10811      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
10812      regs = Bits32(opcode, 7, 0) / 2;
10813
10814      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
10815      // UNPREDICTABLE;
10816      if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10817        return false;
10818
10819      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10820      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10821        return false;
10822
10823      break;
10824
10825    case eEncodingT2:
10826    case eEncodingA2:
10827      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10828      // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10829      // if P == '1' && W == '0' then SEE VLDR;
10830      // if P == U && W == '1' then UNDEFINED;
10831      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
10832        return false;
10833
10834      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
10835      // !), 101 (DB with !)
10836      // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
10837      // UInt(Vd:D); n = UInt(Rn);
10838      single_regs = true;
10839      add = BitIsSet(opcode, 23);
10840      wback = BitIsSet(opcode, 21);
10841      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
10842      n = Bits32(opcode, 19, 16);
10843
10844      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
10845      imm32 = Bits32(opcode, 7, 0) << 2;
10846      regs = Bits32(opcode, 7, 0);
10847
10848      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
10849      // UNPREDICTABLE;
10850      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10851        return false;
10852
10853      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10854      if ((regs == 0) || ((d + regs) > 32))
10855        return false;
10856      break;
10857
10858    default:
10859      return false;
10860    }
10861
10862    RegisterInfo base_reg;
10863    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10864
10865    uint32_t Rn = ReadCoreReg(n, &success);
10866    if (!success)
10867      return false;
10868
10869    // address = if add then R[n] else R[n]-imm32;
10870    addr_t address;
10871    if (add)
10872      address = Rn;
10873    else
10874      address = Rn - imm32;
10875
10876    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10877    EmulateInstruction::Context context;
10878
10879    if (wback) {
10880      uint32_t value;
10881      if (add)
10882        value = Rn + imm32;
10883      else
10884        value = Rn - imm32;
10885
10886      context.type = eContextAdjustBaseRegister;
10887      context.SetImmediateSigned(value - Rn);
10888      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
10889                                 value))
10890        return false;
10891    }
10892
10893    const uint32_t addr_byte_size = GetAddressByteSize();
10894    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10895
10896    context.type = eContextRegisterLoad;
10897
10898    // for r = 0 to regs-1
10899    for (uint32_t r = 0; r < regs; ++r) {
10900      if (single_regs) {
10901        // S[d+r] = MemA[address,4]; address = address+4;
10902        context.SetRegisterPlusOffset(base_reg, address - Rn);
10903
10904        uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
10905        if (!success)
10906          return false;
10907
10908        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
10909                                   start_reg + d + r, data))
10910          return false;
10911
10912        address = address + 4;
10913      } else {
10914        // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
10915        // address+8;
10916        context.SetRegisterPlusOffset(base_reg, address - Rn);
10917        uint32_t word1 =
10918            MemARead(context, address, addr_byte_size, 0, &success);
10919        if (!success)
10920          return false;
10921
10922        context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
10923        uint32_t word2 =
10924            MemARead(context, address + 4, addr_byte_size, 0, &success);
10925        if (!success)
10926          return false;
10927
10928        address = address + 8;
10929        // // Combine the word-aligned words in the correct order for current
10930        // endianness.
10931        // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10932        uint64_t data;
10933        if (GetByteOrder() == eByteOrderBig) {
10934          data = word1;
10935          data = (data << 32) | word2;
10936        } else {
10937          data = word2;
10938          data = (data << 32) | word1;
10939        }
10940
10941        if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
10942                                   start_reg + d + r, data))
10943          return false;
10944      }
10945    }
10946  }
10947  return true;
10948}
10949
10950// A8.6.399 VSTM
10951// Vector Store Multiple stores multiple extension registers to consecutive
10952// memory locations using an address from an
10953// ARM core register.
10954bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
10955                                        const ARMEncoding encoding) {
10956#if 0
10957    if ConditionPassed() then
10958        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10959        address = if add then R[n] else R[n]-imm32;
10960        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10961        for r = 0 to regs-1
10962            if single_regs then
10963                MemA[address,4] = S[d+r]; address = address+4;
10964            else
10965                // Store as two word-aligned words in the correct order for current endianness.
10966                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10967                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10968                address = address+8;
10969#endif
10970
10971  bool success = false;
10972
10973  if (ConditionPassed(opcode)) {
10974    bool single_regs;
10975    bool add;
10976    bool wback;
10977    uint32_t d;
10978    uint32_t n;
10979    uint32_t imm32;
10980    uint32_t regs;
10981
10982    switch (encoding) {
10983    case eEncodingT1:
10984    case eEncodingA1:
10985      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10986      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
10987      // if P == '1' && W == '0' then SEE VSTR;
10988      // if P == U && W == '1' then UNDEFINED;
10989      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
10990        return false;
10991
10992      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
10993      // !), 101 (DB with !)
10994      // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
10995      single_regs = false;
10996      add = BitIsSet(opcode, 23);
10997      wback = BitIsSet(opcode, 21);
10998
10999      // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11000      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11001      n = Bits32(opcode, 19, 16);
11002      imm32 = Bits32(opcode, 7, 0) << 2;
11003
11004      // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11005      regs = Bits32(opcode, 7, 0) / 2;
11006
11007      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11008      // UNPREDICTABLE;
11009      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11010        return false;
11011
11012      // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11013      if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11014        return false;
11015
11016      break;
11017
11018    case eEncodingT2:
11019    case eEncodingA2:
11020      // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11021      // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11022      // if P == '1' && W == '0' then SEE VSTR;
11023      // if P == U && W == '1' then UNDEFINED;
11024      if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
11025        return false;
11026
11027      // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
11028      // !), 101 (DB with !)
11029      // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
11030      // UInt(Vd:D); n = UInt(Rn);
11031      single_regs = true;
11032      add = BitIsSet(opcode, 23);
11033      wback = BitIsSet(opcode, 21);
11034      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11035      n = Bits32(opcode, 19, 16);
11036
11037      // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11038      imm32 = Bits32(opcode, 7, 0) << 2;
11039      regs = Bits32(opcode, 7, 0);
11040
11041      // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
11042      // UNPREDICTABLE;
11043      if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11044        return false;
11045
11046      // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11047      if ((regs == 0) || ((d + regs) > 32))
11048        return false;
11049
11050      break;
11051
11052    default:
11053      return false;
11054    }
11055
11056    RegisterInfo base_reg;
11057    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11058
11059    uint32_t Rn = ReadCoreReg(n, &success);
11060    if (!success)
11061      return false;
11062
11063    // address = if add then R[n] else R[n]-imm32;
11064    addr_t address;
11065    if (add)
11066      address = Rn;
11067    else
11068      address = Rn - imm32;
11069
11070    EmulateInstruction::Context context;
11071    // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11072    if (wback) {
11073      uint32_t value;
11074      if (add)
11075        value = Rn + imm32;
11076      else
11077        value = Rn - imm32;
11078
11079      context.type = eContextAdjustBaseRegister;
11080      context.SetRegisterPlusOffset(base_reg, value - Rn);
11081
11082      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11083                                 value))
11084        return false;
11085    }
11086
11087    const uint32_t addr_byte_size = GetAddressByteSize();
11088    uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11089
11090    context.type = eContextRegisterStore;
11091    // for r = 0 to regs-1
11092    for (uint32_t r = 0; r < regs; ++r) {
11093
11094      if (single_regs) {
11095        // MemA[address,4] = S[d+r]; address = address+4;
11096        uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11097                                             start_reg + d + r, 0, &success);
11098        if (!success)
11099          return false;
11100
11101        RegisterInfo data_reg;
11102        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11103        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11104                                                address - Rn);
11105        if (!MemAWrite(context, address, data, addr_byte_size))
11106          return false;
11107
11108        address = address + 4;
11109      } else {
11110        // // Store as two word-aligned words in the correct order for current
11111        // endianness.
11112        // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
11113        // D[d+r]<31:0>;
11114        // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
11115        // D[d+r]<63:32>;
11116        uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
11117                                             start_reg + d + r, 0, &success);
11118        if (!success)
11119          return false;
11120
11121        RegisterInfo data_reg;
11122        GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
11123
11124        if (GetByteOrder() == eByteOrderBig) {
11125          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11126                                                  address - Rn);
11127          if (!MemAWrite(context, address, Bits64(data, 63, 32),
11128                         addr_byte_size))
11129            return false;
11130
11131          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11132                                                  (address + 4) - Rn);
11133          if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11134                         addr_byte_size))
11135            return false;
11136        } else {
11137          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11138                                                  address - Rn);
11139          if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11140            return false;
11141
11142          context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11143                                                  (address + 4) - Rn);
11144          if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11145                         addr_byte_size))
11146            return false;
11147        }
11148        // address = address+8;
11149        address = address + 8;
11150      }
11151    }
11152  }
11153  return true;
11154}
11155
11156// A8.6.320
11157// This instruction loads a single extension register from memory, using an
11158// address from an ARM core register, with
11159// an optional offset.
11160bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
11161                                        ARMEncoding encoding) {
11162#if 0
11163    if ConditionPassed() then
11164        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11165        base = if n == 15 then Align(PC,4) else R[n];
11166        address = if add then (base + imm32) else (base - imm32);
11167        if single_reg then
11168            S[d] = MemA[address,4];
11169        else
11170            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11171            // Combine the word-aligned words in the correct order for current endianness.
11172            D[d] = if BigEndian() then word1:word2 else word2:word1;
11173#endif
11174
11175  bool success = false;
11176
11177  if (ConditionPassed(opcode)) {
11178    bool single_reg;
11179    bool add;
11180    uint32_t imm32;
11181    uint32_t d;
11182    uint32_t n;
11183
11184    switch (encoding) {
11185    case eEncodingT1:
11186    case eEncodingA1:
11187      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11188      // 32);
11189      single_reg = false;
11190      add = BitIsSet(opcode, 23);
11191      imm32 = Bits32(opcode, 7, 0) << 2;
11192
11193      // d = UInt(D:Vd); n = UInt(Rn);
11194      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11195      n = Bits32(opcode, 19, 16);
11196
11197      break;
11198
11199    case eEncodingT2:
11200    case eEncodingA2:
11201      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11202      single_reg = true;
11203      add = BitIsSet(opcode, 23);
11204      imm32 = Bits32(opcode, 7, 0) << 2;
11205
11206      // d = UInt(Vd:D); n = UInt(Rn);
11207      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11208      n = Bits32(opcode, 19, 16);
11209
11210      break;
11211
11212    default:
11213      return false;
11214    }
11215    RegisterInfo base_reg;
11216    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11217
11218    uint32_t Rn = ReadCoreReg(n, &success);
11219    if (!success)
11220      return false;
11221
11222    // base = if n == 15 then Align(PC,4) else R[n];
11223    uint32_t base;
11224    if (n == 15)
11225      base = AlignPC(Rn);
11226    else
11227      base = Rn;
11228
11229    // address = if add then (base + imm32) else (base - imm32);
11230    addr_t address;
11231    if (add)
11232      address = base + imm32;
11233    else
11234      address = base - imm32;
11235
11236    const uint32_t addr_byte_size = GetAddressByteSize();
11237    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11238
11239    EmulateInstruction::Context context;
11240    context.type = eContextRegisterLoad;
11241    context.SetRegisterPlusOffset(base_reg, address - base);
11242
11243    if (single_reg) {
11244      // S[d] = MemA[address,4];
11245      uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
11246      if (!success)
11247        return false;
11248
11249      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11250                                 data))
11251        return false;
11252    } else {
11253      // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11254      uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
11255      if (!success)
11256        return false;
11257
11258      context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
11259      uint32_t word2 =
11260          MemARead(context, address + 4, addr_byte_size, 0, &success);
11261      if (!success)
11262        return false;
11263      // // Combine the word-aligned words in the correct order for current
11264      // endianness.
11265      // D[d] = if BigEndian() then word1:word2 else word2:word1;
11266      uint64_t data64;
11267      if (GetByteOrder() == eByteOrderBig) {
11268        data64 = word1;
11269        data64 = (data64 << 32) | word2;
11270      } else {
11271        data64 = word2;
11272        data64 = (data64 << 32) | word1;
11273      }
11274
11275      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
11276                                 data64))
11277        return false;
11278    }
11279  }
11280  return true;
11281}
11282
11283// A8.6.400 VSTR
11284// This instruction stores a signle extension register to memory, using an
11285// address from an ARM core register, with an
11286// optional offset.
11287bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
11288                                        ARMEncoding encoding) {
11289#if 0
11290    if ConditionPassed() then
11291        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11292        address = if add then (R[n] + imm32) else (R[n] - imm32);
11293        if single_reg then
11294            MemA[address,4] = S[d];
11295        else
11296            // Store as two word-aligned words in the correct order for current endianness.
11297            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11298            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11299#endif
11300
11301  bool success = false;
11302
11303  if (ConditionPassed(opcode)) {
11304    bool single_reg;
11305    bool add;
11306    uint32_t imm32;
11307    uint32_t d;
11308    uint32_t n;
11309
11310    switch (encoding) {
11311    case eEncodingT1:
11312    case eEncodingA1:
11313      // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
11314      // 32);
11315      single_reg = false;
11316      add = BitIsSet(opcode, 23);
11317      imm32 = Bits32(opcode, 7, 0) << 2;
11318
11319      // d = UInt(D:Vd); n = UInt(Rn);
11320      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11321      n = Bits32(opcode, 19, 16);
11322
11323      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11324      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11325        return false;
11326
11327      break;
11328
11329    case eEncodingT2:
11330    case eEncodingA2:
11331      // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11332      single_reg = true;
11333      add = BitIsSet(opcode, 23);
11334      imm32 = Bits32(opcode, 7, 0) << 2;
11335
11336      // d = UInt(Vd:D); n = UInt(Rn);
11337      d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
11338      n = Bits32(opcode, 19, 16);
11339
11340      // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11341      if ((n == 15) && (CurrentInstrSet() != eModeARM))
11342        return false;
11343
11344      break;
11345
11346    default:
11347      return false;
11348    }
11349
11350    RegisterInfo base_reg;
11351    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11352
11353    uint32_t Rn = ReadCoreReg(n, &success);
11354    if (!success)
11355      return false;
11356
11357    // address = if add then (R[n] + imm32) else (R[n] - imm32);
11358    addr_t address;
11359    if (add)
11360      address = Rn + imm32;
11361    else
11362      address = Rn - imm32;
11363
11364    const uint32_t addr_byte_size = GetAddressByteSize();
11365    uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11366
11367    RegisterInfo data_reg;
11368    GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
11369    EmulateInstruction::Context context;
11370    context.type = eContextRegisterStore;
11371    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
11372
11373    if (single_reg) {
11374      // MemA[address,4] = S[d];
11375      uint32_t data =
11376          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11377      if (!success)
11378        return false;
11379
11380      if (!MemAWrite(context, address, data, addr_byte_size))
11381        return false;
11382    } else {
11383      // // Store as two word-aligned words in the correct order for current
11384      // endianness.
11385      // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11386      // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11387      uint64_t data =
11388          ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
11389      if (!success)
11390        return false;
11391
11392      if (GetByteOrder() == eByteOrderBig) {
11393        if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
11394          return false;
11395
11396        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11397                                                (address + 4) - Rn);
11398        if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
11399                       addr_byte_size))
11400          return false;
11401      } else {
11402        if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
11403          return false;
11404
11405        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11406                                                (address + 4) - Rn);
11407        if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
11408                       addr_byte_size))
11409          return false;
11410      }
11411    }
11412  }
11413  return true;
11414}
11415
11416// A8.6.307 VLDI1 (multiple single elements)
11417// This instruction loads elements from memory into one, two, three or four
11418// registers, without de-interleaving.  Every
11419// element of each register is loaded.
11420bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
11421                                                ARMEncoding encoding) {
11422#if 0
11423    if ConditionPassed() then
11424        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11425        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11426        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11427        for r = 0 to regs-1
11428            for e = 0 to elements-1
11429                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11430                address = address + ebytes;
11431#endif
11432
11433  bool success = false;
11434
11435  if (ConditionPassed(opcode)) {
11436    uint32_t regs;
11437    uint32_t alignment;
11438    uint32_t ebytes;
11439    uint32_t esize;
11440    uint32_t elements;
11441    uint32_t d;
11442    uint32_t n;
11443    uint32_t m;
11444    bool wback;
11445    bool register_index;
11446
11447    switch (encoding) {
11448    case eEncodingT1:
11449    case eEncodingA1: {
11450      // case type of
11451      // when '0111'
11452      // regs = 1; if align<1> == '1' then UNDEFINED;
11453      // when '1010'
11454      // regs = 2; if align == '11' then UNDEFINED;
11455      // when '0110'
11456      // regs = 3; if align<1> == '1' then UNDEFINED;
11457      // when '0010'
11458      // regs = 4;
11459      // otherwise
11460      // SEE 'Related encodings';
11461      uint32_t type = Bits32(opcode, 11, 8);
11462      uint32_t align = Bits32(opcode, 5, 4);
11463      if (type == 7) // '0111'
11464      {
11465        regs = 1;
11466        if (BitIsSet(align, 1))
11467          return false;
11468      } else if (type == 10) // '1010'
11469      {
11470        regs = 2;
11471        if (align == 3)
11472          return false;
11473
11474      } else if (type == 6) // '0110'
11475      {
11476        regs = 3;
11477        if (BitIsSet(align, 1))
11478          return false;
11479      } else if (type == 2) // '0010'
11480      {
11481        regs = 4;
11482      } else
11483        return false;
11484
11485      // alignment = if align == '00' then 1 else 4 << UInt(align);
11486      if (align == 0)
11487        alignment = 1;
11488      else
11489        alignment = 4 << align;
11490
11491      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11492      ebytes = 1 << Bits32(opcode, 7, 6);
11493      esize = 8 * ebytes;
11494      elements = 8 / ebytes;
11495
11496      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11497      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11498      n = Bits32(opcode, 19, 15);
11499      m = Bits32(opcode, 3, 0);
11500
11501      // wback = (m != 15); register_index = (m != 15 && m != 13);
11502      wback = (m != 15);
11503      register_index = ((m != 15) && (m != 13));
11504
11505      // if d+regs > 32 then UNPREDICTABLE;
11506      if ((d + regs) > 32)
11507        return false;
11508    } break;
11509
11510    default:
11511      return false;
11512    }
11513
11514    RegisterInfo base_reg;
11515    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11516
11517    uint32_t Rn = ReadCoreReg(n, &success);
11518    if (!success)
11519      return false;
11520
11521    // address = R[n]; if (address MOD alignment) != 0 then
11522    // GenerateAlignmentException();
11523    addr_t address = Rn;
11524    if ((address % alignment) != 0)
11525      return false;
11526
11527    EmulateInstruction::Context context;
11528    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11529    if (wback) {
11530      uint32_t Rm = ReadCoreReg(m, &success);
11531      if (!success)
11532        return false;
11533
11534      uint32_t offset;
11535      if (register_index)
11536        offset = Rm;
11537      else
11538        offset = 8 * regs;
11539
11540      uint32_t value = Rn + offset;
11541      context.type = eContextAdjustBaseRegister;
11542      context.SetRegisterPlusOffset(base_reg, offset);
11543
11544      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11545                                 value))
11546        return false;
11547    }
11548
11549    // for r = 0 to regs-1
11550    for (uint32_t r = 0; r < regs; ++r) {
11551      // for e = 0 to elements-1
11552      uint64_t assembled_data = 0;
11553      for (uint32_t e = 0; e < elements; ++e) {
11554        // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11555        context.type = eContextRegisterLoad;
11556        context.SetRegisterPlusOffset(base_reg, address - Rn);
11557        uint64_t data = MemURead(context, address, ebytes, 0, &success);
11558        if (!success)
11559          return false;
11560
11561        assembled_data =
11562            (data << (e * esize)) |
11563            assembled_data; // New data goes to the left of existing data
11564
11565        // address = address + ebytes;
11566        address = address + ebytes;
11567      }
11568      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
11569                                 assembled_data))
11570        return false;
11571    }
11572  }
11573  return true;
11574}
11575
11576// A8.6.308 VLD1 (single element to one lane)
11577//
11578bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
11579                                              const ARMEncoding encoding) {
11580#if 0
11581    if ConditionPassed() then
11582        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11583        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11584        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11585        Elem[D[d],index,esize] = MemU[address,ebytes];
11586#endif
11587
11588  bool success = false;
11589
11590  if (ConditionPassed(opcode)) {
11591    uint32_t ebytes;
11592    uint32_t esize;
11593    uint32_t index;
11594    uint32_t alignment;
11595    uint32_t d;
11596    uint32_t n;
11597    uint32_t m;
11598    bool wback;
11599    bool register_index;
11600
11601    switch (encoding) {
11602    case eEncodingT1:
11603    case eEncodingA1: {
11604      uint32_t size = Bits32(opcode, 11, 10);
11605      uint32_t index_align = Bits32(opcode, 7, 4);
11606      // if size == '11' then SEE VLD1 (single element to all lanes);
11607      if (size == 3)
11608        return EmulateVLD1SingleAll(opcode, encoding);
11609      // case size of
11610      if (size == 0) // when '00'
11611      {
11612        // if index_align<0> != '0' then UNDEFINED;
11613        if (BitIsClear(index_align, 0))
11614          return false;
11615
11616        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11617        ebytes = 1;
11618        esize = 8;
11619        index = Bits32(index_align, 3, 1);
11620        alignment = 1;
11621      } else if (size == 1) // when '01'
11622      {
11623        // if index_align<1> != '0' then UNDEFINED;
11624        if (BitIsClear(index_align, 1))
11625          return false;
11626
11627        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11628        ebytes = 2;
11629        esize = 16;
11630        index = Bits32(index_align, 3, 2);
11631
11632        // alignment = if index_align<0> == '0' then 1 else 2;
11633        if (BitIsClear(index_align, 0))
11634          alignment = 1;
11635        else
11636          alignment = 2;
11637      } else if (size == 2) // when '10'
11638      {
11639        // if index_align<2> != '0' then UNDEFINED;
11640        if (BitIsClear(index_align, 2))
11641          return false;
11642
11643        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
11644        // UNDEFINED;
11645        if ((Bits32(index_align, 1, 0) != 0) &&
11646            (Bits32(index_align, 1, 0) != 3))
11647          return false;
11648
11649        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11650        ebytes = 4;
11651        esize = 32;
11652        index = Bit32(index_align, 3);
11653
11654        // alignment = if index_align<1:0> == '00' then 1 else 4;
11655        if (Bits32(index_align, 1, 0) == 0)
11656          alignment = 1;
11657        else
11658          alignment = 4;
11659      } else {
11660        return false;
11661      }
11662      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11663      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11664      n = Bits32(opcode, 19, 16);
11665      m = Bits32(opcode, 3, 0);
11666
11667      // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
11668      // then UNPREDICTABLE;
11669      wback = (m != 15);
11670      register_index = ((m != 15) && (m != 13));
11671
11672      if (n == 15)
11673        return false;
11674
11675    } break;
11676
11677    default:
11678      return false;
11679    }
11680
11681    RegisterInfo base_reg;
11682    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11683
11684    uint32_t Rn = ReadCoreReg(n, &success);
11685    if (!success)
11686      return false;
11687
11688    // address = R[n]; if (address MOD alignment) != 0 then
11689    // GenerateAlignmentException();
11690    addr_t address = Rn;
11691    if ((address % alignment) != 0)
11692      return false;
11693
11694    EmulateInstruction::Context context;
11695    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11696    if (wback) {
11697      uint32_t Rm = ReadCoreReg(m, &success);
11698      if (!success)
11699        return false;
11700
11701      uint32_t offset;
11702      if (register_index)
11703        offset = Rm;
11704      else
11705        offset = ebytes;
11706
11707      uint32_t value = Rn + offset;
11708
11709      context.type = eContextAdjustBaseRegister;
11710      context.SetRegisterPlusOffset(base_reg, offset);
11711
11712      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11713                                 value))
11714        return false;
11715    }
11716
11717    // Elem[D[d],index,esize] = MemU[address,ebytes];
11718    uint32_t element = MemURead(context, address, esize, 0, &success);
11719    if (!success)
11720      return false;
11721
11722    element = element << (index * esize);
11723
11724    uint64_t reg_data =
11725        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11726    if (!success)
11727      return false;
11728
11729    uint64_t all_ones = -1;
11730    uint64_t mask = all_ones
11731                    << ((index + 1) * esize); // mask is all 1's to left of
11732                                              // where 'element' goes, & all 0's
11733    // at element & to the right of element.
11734    if (index > 0)
11735      mask = mask | Bits64(all_ones, (index * esize) - 1,
11736                           0); // add 1's to the right of where 'element' goes.
11737    // now mask should be 0's where element goes & 1's
11738    // everywhere else.
11739
11740    uint64_t masked_reg =
11741        reg_data & mask; // Take original reg value & zero out 'element' bits
11742    reg_data =
11743        masked_reg & element; // Put 'element' into those bits in reg_data.
11744
11745    context.type = eContextRegisterLoad;
11746    if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
11747                               reg_data))
11748      return false;
11749  }
11750  return true;
11751}
11752
11753// A8.6.391 VST1 (multiple single elements)
11754// Vector Store (multiple single elements) stores elements to memory from one,
11755// two, three, or four registers, without
11756// interleaving.  Every element of each register is stored.
11757bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
11758                                                ARMEncoding encoding) {
11759#if 0
11760    if ConditionPassed() then
11761        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11762        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11763        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11764        for r = 0 to regs-1
11765            for e = 0 to elements-1
11766                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11767                address = address + ebytes;
11768#endif
11769
11770  bool success = false;
11771
11772  if (ConditionPassed(opcode)) {
11773    uint32_t regs;
11774    uint32_t alignment;
11775    uint32_t ebytes;
11776    uint32_t esize;
11777    uint32_t elements;
11778    uint32_t d;
11779    uint32_t n;
11780    uint32_t m;
11781    bool wback;
11782    bool register_index;
11783
11784    switch (encoding) {
11785    case eEncodingT1:
11786    case eEncodingA1: {
11787      uint32_t type = Bits32(opcode, 11, 8);
11788      uint32_t align = Bits32(opcode, 5, 4);
11789
11790      // case type of
11791      if (type == 7) // when '0111'
11792      {
11793        // regs = 1; if align<1> == '1' then UNDEFINED;
11794        regs = 1;
11795        if (BitIsSet(align, 1))
11796          return false;
11797      } else if (type == 10) // when '1010'
11798      {
11799        // regs = 2; if align == '11' then UNDEFINED;
11800        regs = 2;
11801        if (align == 3)
11802          return false;
11803      } else if (type == 6) // when '0110'
11804      {
11805        // regs = 3; if align<1> == '1' then UNDEFINED;
11806        regs = 3;
11807        if (BitIsSet(align, 1))
11808          return false;
11809      } else if (type == 2) // when '0010'
11810        // regs = 4;
11811        regs = 4;
11812      else // otherwise
11813        // SEE 'Related encodings';
11814        return false;
11815
11816      // alignment = if align == '00' then 1 else 4 << UInt(align);
11817      if (align == 0)
11818        alignment = 1;
11819      else
11820        alignment = 4 << align;
11821
11822      // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11823      ebytes = 1 << Bits32(opcode, 7, 6);
11824      esize = 8 * ebytes;
11825      elements = 8 / ebytes;
11826
11827      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11828      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
11829      n = Bits32(opcode, 19, 16);
11830      m = Bits32(opcode, 3, 0);
11831
11832      // wback = (m != 15); register_index = (m != 15 && m != 13);
11833      wback = (m != 15);
11834      register_index = ((m != 15) && (m != 13));
11835
11836      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11837      if ((d + regs) > 32)
11838        return false;
11839
11840      if (n == 15)
11841        return false;
11842
11843    } break;
11844
11845    default:
11846      return false;
11847    }
11848
11849    RegisterInfo base_reg;
11850    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11851
11852    uint32_t Rn = ReadCoreReg(n, &success);
11853    if (!success)
11854      return false;
11855
11856    // address = R[n]; if (address MOD alignment) != 0 then
11857    // GenerateAlignmentException();
11858    addr_t address = Rn;
11859    if ((address % alignment) != 0)
11860      return false;
11861
11862    EmulateInstruction::Context context;
11863    // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11864    if (wback) {
11865      uint32_t Rm = ReadCoreReg(m, &success);
11866      if (!success)
11867        return false;
11868
11869      uint32_t offset;
11870      if (register_index)
11871        offset = Rm;
11872      else
11873        offset = 8 * regs;
11874
11875      context.type = eContextAdjustBaseRegister;
11876      context.SetRegisterPlusOffset(base_reg, offset);
11877
11878      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
11879                                 Rn + offset))
11880        return false;
11881    }
11882
11883    RegisterInfo data_reg;
11884    context.type = eContextRegisterStore;
11885    // for r = 0 to regs-1
11886    for (uint32_t r = 0; r < regs; ++r) {
11887      GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11888      uint64_t register_data = ReadRegisterUnsigned(
11889          eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11890      if (!success)
11891        return false;
11892
11893      // for e = 0 to elements-1
11894      for (uint32_t e = 0; e < elements; ++e) {
11895        // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11896        uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
11897
11898        context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
11899                                                address - Rn);
11900        if (!MemUWrite(context, address, word, ebytes))
11901          return false;
11902
11903        // address = address + ebytes;
11904        address = address + ebytes;
11905      }
11906    }
11907  }
11908  return true;
11909}
11910
11911// A8.6.392 VST1 (single element from one lane)
11912// This instruction stores one element to memory from one element of a register.
11913bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
11914                                              ARMEncoding encoding) {
11915#if 0
11916    if ConditionPassed() then
11917        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11918        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11919        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11920        MemU[address,ebytes] = Elem[D[d],index,esize];
11921#endif
11922
11923  bool success = false;
11924
11925  if (ConditionPassed(opcode)) {
11926    uint32_t ebytes;
11927    uint32_t esize;
11928    uint32_t index;
11929    uint32_t alignment;
11930    uint32_t d;
11931    uint32_t n;
11932    uint32_t m;
11933    bool wback;
11934    bool register_index;
11935
11936    switch (encoding) {
11937    case eEncodingT1:
11938    case eEncodingA1: {
11939      uint32_t size = Bits32(opcode, 11, 10);
11940      uint32_t index_align = Bits32(opcode, 7, 4);
11941
11942      // if size == '11' then UNDEFINED;
11943      if (size == 3)
11944        return false;
11945
11946      // case size of
11947      if (size == 0) // when '00'
11948      {
11949        // if index_align<0> != '0' then UNDEFINED;
11950        if (BitIsClear(index_align, 0))
11951          return false;
11952        // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11953        ebytes = 1;
11954        esize = 8;
11955        index = Bits32(index_align, 3, 1);
11956        alignment = 1;
11957      } else if (size == 1) // when '01'
11958      {
11959        // if index_align<1> != '0' then UNDEFINED;
11960        if (BitIsClear(index_align, 1))
11961          return false;
11962
11963        // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11964        ebytes = 2;
11965        esize = 16;
11966        index = Bits32(index_align, 3, 2);
11967
11968        // alignment = if index_align<0> == '0' then 1 else 2;
11969        if (BitIsClear(index_align, 0))
11970          alignment = 1;
11971        else
11972          alignment = 2;
11973      } else if (size == 2) // when '10'
11974      {
11975        // if index_align<2> != '0' then UNDEFINED;
11976        if (BitIsClear(index_align, 2))
11977          return false;
11978
11979        // if index_align<1:0> != '00' && index_align<1:0> != '11' then
11980        // UNDEFINED;
11981        if ((Bits32(index_align, 1, 0) != 0) &&
11982            (Bits32(index_align, 1, 0) != 3))
11983          return false;
11984
11985        // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11986        ebytes = 4;
11987        esize = 32;
11988        index = Bit32(index_align, 3);
11989
11990        // alignment = if index_align<1:0> == '00' then 1 else 4;
11991        if (Bits32(index_align, 1, 0) == 0)
11992          alignment = 1;
11993        else
11994          alignment = 4;
11995      } else {
11996        return false;
11997      }
11998      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11999      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12000      n = Bits32(opcode, 19, 16);
12001      m = Bits32(opcode, 3, 0);
12002
12003      // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15
12004      // then UNPREDICTABLE;
12005      wback = (m != 15);
12006      register_index = ((m != 15) && (m != 13));
12007
12008      if (n == 15)
12009        return false;
12010    } break;
12011
12012    default:
12013      return false;
12014    }
12015
12016    RegisterInfo base_reg;
12017    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12018
12019    uint32_t Rn = ReadCoreReg(n, &success);
12020    if (!success)
12021      return false;
12022
12023    // address = R[n]; if (address MOD alignment) != 0 then
12024    // GenerateAlignmentException();
12025    addr_t address = Rn;
12026    if ((address % alignment) != 0)
12027      return false;
12028
12029    EmulateInstruction::Context context;
12030    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12031    if (wback) {
12032      uint32_t Rm = ReadCoreReg(m, &success);
12033      if (!success)
12034        return false;
12035
12036      uint32_t offset;
12037      if (register_index)
12038        offset = Rm;
12039      else
12040        offset = ebytes;
12041
12042      context.type = eContextAdjustBaseRegister;
12043      context.SetRegisterPlusOffset(base_reg, offset);
12044
12045      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12046                                 Rn + offset))
12047        return false;
12048    }
12049
12050    // MemU[address,ebytes] = Elem[D[d],index,esize];
12051    uint64_t register_data =
12052        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12053    if (!success)
12054      return false;
12055
12056    uint64_t word =
12057        Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
12058
12059    RegisterInfo data_reg;
12060    GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12061    context.type = eContextRegisterStore;
12062    context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
12063
12064    if (!MemUWrite(context, address, word, ebytes))
12065      return false;
12066  }
12067  return true;
12068}
12069
12070// A8.6.309 VLD1 (single element to all lanes)
12071// This instruction loads one element from memory into every element of one or
12072// two vectors.
12073bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
12074                                                 const ARMEncoding encoding) {
12075#if 0
12076    if ConditionPassed() then
12077        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12078        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12079        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12080        replicated_element = Replicate(MemU[address,ebytes], elements);
12081        for r = 0 to regs-1
12082            D[d+r] = replicated_element;
12083#endif
12084
12085  bool success = false;
12086
12087  if (ConditionPassed(opcode)) {
12088    uint32_t ebytes;
12089    uint32_t elements;
12090    uint32_t regs;
12091    uint32_t alignment;
12092    uint32_t d;
12093    uint32_t n;
12094    uint32_t m;
12095    bool wback;
12096    bool register_index;
12097
12098    switch (encoding) {
12099    case eEncodingT1:
12100    case eEncodingA1: {
12101      // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12102      uint32_t size = Bits32(opcode, 7, 6);
12103      if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
12104        return false;
12105
12106      // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
12107      // then 1 else 2;
12108      ebytes = 1 << size;
12109      elements = 8 / ebytes;
12110      if (BitIsClear(opcode, 5))
12111        regs = 1;
12112      else
12113        regs = 2;
12114
12115      // alignment = if a == '0' then 1 else ebytes;
12116      if (BitIsClear(opcode, 4))
12117        alignment = 1;
12118      else
12119        alignment = ebytes;
12120
12121      // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12122      d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
12123      n = Bits32(opcode, 19, 16);
12124      m = Bits32(opcode, 3, 0);
12125
12126      // wback = (m != 15); register_index = (m != 15 && m != 13);
12127      wback = (m != 15);
12128      register_index = ((m != 15) && (m != 13));
12129
12130      // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12131      if ((d + regs) > 32)
12132        return false;
12133
12134      if (n == 15)
12135        return false;
12136    } break;
12137
12138    default:
12139      return false;
12140    }
12141
12142    RegisterInfo base_reg;
12143    GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12144
12145    uint32_t Rn = ReadCoreReg(n, &success);
12146    if (!success)
12147      return false;
12148
12149    // address = R[n]; if (address MOD alignment) != 0 then
12150    // GenerateAlignmentException();
12151    addr_t address = Rn;
12152    if ((address % alignment) != 0)
12153      return false;
12154
12155    EmulateInstruction::Context context;
12156    // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12157    if (wback) {
12158      uint32_t Rm = ReadCoreReg(m, &success);
12159      if (!success)
12160        return false;
12161
12162      uint32_t offset;
12163      if (register_index)
12164        offset = Rm;
12165      else
12166        offset = ebytes;
12167
12168      context.type = eContextAdjustBaseRegister;
12169      context.SetRegisterPlusOffset(base_reg, offset);
12170
12171      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
12172                                 Rn + offset))
12173        return false;
12174    }
12175
12176    // replicated_element = Replicate(MemU[address,ebytes], elements);
12177
12178    context.type = eContextRegisterLoad;
12179    uint64_t word = MemURead(context, address, ebytes, 0, &success);
12180    if (!success)
12181      return false;
12182
12183    uint64_t replicated_element = 0;
12184    uint32_t esize = ebytes * 8;
12185    for (uint32_t e = 0; e < elements; ++e)
12186      replicated_element =
12187          (replicated_element << esize) | Bits64(word, esize - 1, 0);
12188
12189    // for r = 0 to regs-1
12190    for (uint32_t r = 0; r < regs; ++r) {
12191      // D[d+r] = replicated_element;
12192      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
12193                                 replicated_element))
12194        return false;
12195    }
12196  }
12197  return true;
12198}
12199
12200// B6.2.13 SUBS PC, LR and related instructions
12201// The SUBS PC, LR, #<const? instruction provides an exception return without
12202// the use of the stack.  It subtracts the
12203// immediate constant from the LR, branches to the resulting address, and also
12204// copies the SPSR to the CPSR.
12205bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
12206                                               const ARMEncoding encoding) {
12207#if 0
12208    if ConditionPassed() then
12209        EncodingSpecificOperations();
12210        if CurrentInstrSet() == InstrSet_ThumbEE then
12211            UNPREDICTABLE;
12212        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12213        case opcode of
12214            when '0000' result = R[n] AND operand2; // AND
12215            when '0001' result = R[n] EOR operand2; // EOR
12216            when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12217            when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12218            when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12219            when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12220            when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12221            when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12222            when '1100' result = R[n] OR operand2; // ORR
12223            when '1101' result = operand2; // MOV
12224            when '1110' result = R[n] AND NOT(operand2); // BIC
12225            when '1111' result = NOT(operand2); // MVN
12226        CPSRWriteByInstr(SPSR[], '1111', TRUE);
12227        BranchWritePC(result);
12228#endif
12229
12230  bool success = false;
12231
12232  if (ConditionPassed(opcode)) {
12233    uint32_t n;
12234    uint32_t m;
12235    uint32_t imm32;
12236    bool register_form;
12237    ARM_ShifterType shift_t;
12238    uint32_t shift_n;
12239    uint32_t code;
12240
12241    switch (encoding) {
12242    case eEncodingT1:
12243      // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12244      // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode =
12245      // '0010'; // = SUB
12246      n = 14;
12247      imm32 = Bits32(opcode, 7, 0);
12248      register_form = false;
12249      code = 2;
12250
12251      // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12252      if (InITBlock() && !LastInITBlock())
12253        return false;
12254
12255      break;
12256
12257    case eEncodingA1:
12258      // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12259      n = Bits32(opcode, 19, 16);
12260      imm32 = ARMExpandImm(opcode);
12261      register_form = false;
12262      code = Bits32(opcode, 24, 21);
12263
12264      break;
12265
12266    case eEncodingA2:
12267      // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12268      n = Bits32(opcode, 19, 16);
12269      m = Bits32(opcode, 3, 0);
12270      register_form = true;
12271
12272      // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12273      shift_n = DecodeImmShiftARM(opcode, shift_t);
12274
12275      break;
12276
12277    default:
12278      return false;
12279    }
12280
12281    // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
12282    // else imm32;
12283    uint32_t operand2;
12284    if (register_form) {
12285      uint32_t Rm = ReadCoreReg(m, &success);
12286      if (!success)
12287        return false;
12288
12289      operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
12290      if (!success)
12291        return false;
12292    } else {
12293      operand2 = imm32;
12294    }
12295
12296    uint32_t Rn = ReadCoreReg(n, &success);
12297    if (!success)
12298      return false;
12299
12300    AddWithCarryResult result;
12301
12302    // case opcode of
12303    switch (code) {
12304    case 0: // when '0000'
12305      // result = R[n] AND operand2; // AND
12306      result.result = Rn & operand2;
12307      break;
12308
12309    case 1: // when '0001'
12310      // result = R[n] EOR operand2; // EOR
12311      result.result = Rn ^ operand2;
12312      break;
12313
12314    case 2: // when '0010'
12315      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12316      result = AddWithCarry(Rn, ~(operand2), 1);
12317      break;
12318
12319    case 3: // when '0011'
12320      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12321      result = AddWithCarry(~(Rn), operand2, 1);
12322      break;
12323
12324    case 4: // when '0100'
12325      // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12326      result = AddWithCarry(Rn, operand2, 0);
12327      break;
12328
12329    case 5: // when '0101'
12330      // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12331      result = AddWithCarry(Rn, operand2, APSR_C);
12332      break;
12333
12334    case 6: // when '0110'
12335      // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12336      result = AddWithCarry(Rn, ~(operand2), APSR_C);
12337      break;
12338
12339    case 7: // when '0111'
12340      // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12341      result = AddWithCarry(~(Rn), operand2, APSR_C);
12342      break;
12343
12344    case 10: // when '1100'
12345      // result = R[n] OR operand2; // ORR
12346      result.result = Rn | operand2;
12347      break;
12348
12349    case 11: // when '1101'
12350      // result = operand2; // MOV
12351      result.result = operand2;
12352      break;
12353
12354    case 12: // when '1110'
12355      // result = R[n] AND NOT(operand2); // BIC
12356      result.result = Rn & ~(operand2);
12357      break;
12358
12359    case 15: // when '1111'
12360      // result = NOT(operand2); // MVN
12361      result.result = ~(operand2);
12362      break;
12363
12364    default:
12365      return false;
12366    }
12367    // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12368
12369    // For now, in emulation mode, we don't have access to the SPSR, so we will
12370    // use the CPSR instead, and hope for
12371    // the best.
12372    uint32_t spsr =
12373        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12374    if (!success)
12375      return false;
12376
12377    CPSRWriteByInstr(spsr, 15, true);
12378
12379    // BranchWritePC(result);
12380    EmulateInstruction::Context context;
12381    context.type = eContextAdjustPC;
12382    context.SetImmediate(result.result);
12383
12384    BranchWritePC(context, result.result);
12385  }
12386  return true;
12387}
12388
12389EmulateInstructionARM::ARMOpcode *
12390EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
12391                                                  uint32_t arm_isa) {
12392  static ARMOpcode g_arm_opcodes[] = {
12393      //----------------------------------------------------------------------
12394      // Prologue instructions
12395      //----------------------------------------------------------------------
12396
12397      // push register(s)
12398      {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12399       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12400      {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12401       &EmulateInstructionARM::EmulatePUSH, "push <register>"},
12402
12403      // set r7 to point to a stack offset
12404      {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12405       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
12406      {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12407       &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12408      // copy the stack pointer to ip
12409      {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
12410       &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
12411      {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12412       &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
12413      {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12414       &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12415
12416      // adjust the stack pointer
12417      {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12418       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12419      {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12420       &EmulateInstructionARM::EmulateSUBSPReg,
12421       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12422
12423      // push one register
12424      // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12425      {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12426       &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
12427
12428      // vector push consecutive extension register(s)
12429      {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12430       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12431      {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12432       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12433
12434      //----------------------------------------------------------------------
12435      // Epilogue instructions
12436      //----------------------------------------------------------------------
12437
12438      {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12439       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12440      {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
12441       &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12442      {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
12443       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12444      {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12445       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12446
12447      //----------------------------------------------------------------------
12448      // Supervisor Call (previously Software Interrupt)
12449      //----------------------------------------------------------------------
12450      {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12451       &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12452
12453      //----------------------------------------------------------------------
12454      // Branch instructions
12455      //----------------------------------------------------------------------
12456      // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
12457      // "bl <label>".
12458      {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
12459       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12460      {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12461       &EmulateInstructionARM::EmulateB, "b #imm24"},
12462      {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12463       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12464      {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
12465       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12466      // for example, "bx lr"
12467      {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
12468       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12469      // bxj
12470      {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
12471       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12472
12473      //----------------------------------------------------------------------
12474      // Data-processing instructions
12475      //----------------------------------------------------------------------
12476      // adc (immediate)
12477      {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12478       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12479      // adc (register)
12480      {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12481       &EmulateInstructionARM::EmulateADCReg,
12482       "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12483      // add (immediate)
12484      {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12485       &EmulateInstructionARM::EmulateADDImmARM,
12486       "add{s}<c> <Rd>, <Rn>, #const"},
12487      // add (register)
12488      {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12489       &EmulateInstructionARM::EmulateADDReg,
12490       "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12491      // add (register-shifted register)
12492      {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12493       &EmulateInstructionARM::EmulateADDRegShift,
12494       "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12495      // adr
12496      {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12497       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12498      {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12499       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12500      // and (immediate)
12501      {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12502       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12503      // and (register)
12504      {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12505       &EmulateInstructionARM::EmulateANDReg,
12506       "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12507      // bic (immediate)
12508      {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12509       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12510      // bic (register)
12511      {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12512       &EmulateInstructionARM::EmulateBICReg,
12513       "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12514      // eor (immediate)
12515      {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12516       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12517      // eor (register)
12518      {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12519       &EmulateInstructionARM::EmulateEORReg,
12520       "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12521      // orr (immediate)
12522      {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12523       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12524      // orr (register)
12525      {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12526       &EmulateInstructionARM::EmulateORRReg,
12527       "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12528      // rsb (immediate)
12529      {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12530       &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12531      // rsb (register)
12532      {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12533       &EmulateInstructionARM::EmulateRSBReg,
12534       "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12535      // rsc (immediate)
12536      {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12537       &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12538      // rsc (register)
12539      {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12540       &EmulateInstructionARM::EmulateRSCReg,
12541       "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12542      // sbc (immediate)
12543      {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12544       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12545      // sbc (register)
12546      {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12547       &EmulateInstructionARM::EmulateSBCReg,
12548       "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12549      // sub (immediate, ARM)
12550      {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12551       &EmulateInstructionARM::EmulateSUBImmARM,
12552       "sub{s}<c> <Rd>, <Rn>, #<const>"},
12553      // sub (sp minus immediate)
12554      {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12555       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12556      // sub (register)
12557      {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12558       &EmulateInstructionARM::EmulateSUBReg,
12559       "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12560      // teq (immediate)
12561      {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12562       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12563      // teq (register)
12564      {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12565       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12566      // tst (immediate)
12567      {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12568       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12569      // tst (register)
12570      {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12571       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12572
12573      // mov (immediate)
12574      {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12575       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12576      {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
12577       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
12578      // mov (register)
12579      {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12580       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12581      // mvn (immediate)
12582      {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12583       &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12584      // mvn (register)
12585      {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12586       &EmulateInstructionARM::EmulateMVNReg,
12587       "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12588      // cmn (immediate)
12589      {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12590       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12591      // cmn (register)
12592      {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12593       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12594      // cmp (immediate)
12595      {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12596       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12597      // cmp (register)
12598      {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12599       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12600      // asr (immediate)
12601      {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
12602       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12603      // asr (register)
12604      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
12605       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12606      // lsl (immediate)
12607      {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12608       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12609      // lsl (register)
12610      {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
12611       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12612      // lsr (immediate)
12613      {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
12614       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12615      // lsr (register)
12616      {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
12617       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12618      // rrx is a special case encoding of ror (immediate)
12619      {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
12620       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12621      // ror (immediate)
12622      {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
12623       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12624      // ror (register)
12625      {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
12626       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12627      // mul
12628      {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
12629       &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
12630
12631      // subs pc, lr and related instructions
12632      {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12633       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
12634       "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
12635      {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
12636       &EmulateInstructionARM::EmulateSUBSPcLrEtc,
12637       "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
12638
12639      //----------------------------------------------------------------------
12640      // Load instructions
12641      //----------------------------------------------------------------------
12642      {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12643       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
12644      {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12645       &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
12646      {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12647       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
12648      {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12649       &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
12650      {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12651       &EmulateInstructionARM::EmulateLDRImmediateARM,
12652       "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
12653      {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12654       &EmulateInstructionARM::EmulateLDRRegister,
12655       "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
12656      {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12657       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12658      {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12659       &EmulateInstructionARM::EmulateLDRBRegister,
12660       "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
12661      {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12662       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
12663      {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12664       &EmulateInstructionARM::EmulateLDRHRegister,
12665       "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
12666      {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12667       &EmulateInstructionARM::EmulateLDRSBImmediate,
12668       "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
12669      {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12670       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
12671      {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12672       &EmulateInstructionARM::EmulateLDRSBRegister,
12673       "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
12674      {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12675       &EmulateInstructionARM::EmulateLDRSHImmediate,
12676       "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12677      {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12678       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
12679      {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12680       &EmulateInstructionARM::EmulateLDRSHRegister,
12681       "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
12682      {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
12683       &EmulateInstructionARM::EmulateLDRDImmediate,
12684       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12685      {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
12686       &EmulateInstructionARM::EmulateLDRDRegister,
12687       "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12688      {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
12689       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12690      {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
12691       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12692      {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
12693       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12694      {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
12695       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12696      {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
12697       &EmulateInstructionARM::EmulateVLD1Multiple,
12698       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12699      {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
12700       &EmulateInstructionARM::EmulateVLD1Single,
12701       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12702      {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
12703       &EmulateInstructionARM::EmulateVLD1SingleAll,
12704       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12705
12706      //----------------------------------------------------------------------
12707      // Store instructions
12708      //----------------------------------------------------------------------
12709      {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12710       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
12711      {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12712       &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
12713      {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12714       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
12715      {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12716       &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
12717      {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12718       &EmulateInstructionARM::EmulateSTRRegister,
12719       "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
12720      {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
12721       &EmulateInstructionARM::EmulateSTRHRegister,
12722       "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
12723      {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
12724       &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12725      {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12726       &EmulateInstructionARM::EmulateSTRBImmARM,
12727       "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12728      {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
12729       &EmulateInstructionARM::EmulateSTRImmARM,
12730       "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12731      {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
12732       &EmulateInstructionARM::EmulateSTRDImm,
12733       "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12734      {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
12735       &EmulateInstructionARM::EmulateSTRDReg,
12736       "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12737      {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
12738       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12739      {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
12740       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12741      {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
12742       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12743      {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
12744       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12745      {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
12746       &EmulateInstructionARM::EmulateVST1Multiple,
12747       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12748      {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
12749       &EmulateInstructionARM::EmulateVST1Single,
12750       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12751
12752      //----------------------------------------------------------------------
12753      // Other instructions
12754      //----------------------------------------------------------------------
12755      {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
12756       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
12757      {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
12758       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
12759      {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
12760       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
12761      {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
12762       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
12763      {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
12764       &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
12765
12766  };
12767  static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12768
12769  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
12770    if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12771        (g_arm_opcodes[i].variants & arm_isa) != 0)
12772      return &g_arm_opcodes[i];
12773  }
12774  return NULL;
12775}
12776
12777EmulateInstructionARM::ARMOpcode *
12778EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
12779                                                    uint32_t arm_isa) {
12780
12781  static ARMOpcode g_thumb_opcodes[] = {
12782      //----------------------------------------------------------------------
12783      // Prologue instructions
12784      //----------------------------------------------------------------------
12785
12786      // push register(s)
12787      {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
12788       &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
12789      {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12790       &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
12791      {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
12792       &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
12793
12794      // set r7 to point to a stack offset
12795      {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
12796       &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
12797      // copy the stack pointer to r7
12798      {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
12799       &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
12800      // move from high register to low register (comes after "mov r7, sp" to
12801      // resolve ambiguity)
12802      {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
12803       &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
12804
12805      // PC-relative load into register (see also EmulateADDSPRm)
12806      {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
12807       &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12808
12809      // adjust the stack pointer
12810      {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
12811       &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12812      {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
12813       &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12814      {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12815       &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12816      {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
12817       &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12818      {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12819       &EmulateInstructionARM::EmulateSUBSPReg,
12820       "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
12821
12822      // vector push consecutive extension register(s)
12823      {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12824       &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12825      {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12826       &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12827
12828      //----------------------------------------------------------------------
12829      // Epilogue instructions
12830      //----------------------------------------------------------------------
12831
12832      {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
12833       &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12834      {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
12835       &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12836      {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
12837       &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12838      {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12839       &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
12840      {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
12841       &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
12842      {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12843       &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12844      {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12845       &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12846
12847      //----------------------------------------------------------------------
12848      // Supervisor Call (previously Software Interrupt)
12849      //----------------------------------------------------------------------
12850      {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
12851       &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12852
12853      //----------------------------------------------------------------------
12854      // If Then makes up to four following instructions conditional.
12855      //----------------------------------------------------------------------
12856      // The next 5 opcode _must_ come before the if then instruction
12857      {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
12858       &EmulateInstructionARM::EmulateNop, "nop"},
12859      {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
12860       &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12861      {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
12862       &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12863      {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
12864       &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12865      {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
12866       &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12867      {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
12868       &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12869
12870      //----------------------------------------------------------------------
12871      // Branch instructions
12872      //----------------------------------------------------------------------
12873      // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12874      {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
12875       &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12876      {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
12877       &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12878      {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
12879       &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12880      {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
12881       &EmulateInstructionARM::EmulateB,
12882       "b<c>.w #imm8 (outside or last in IT)"},
12883      // J1 == J2 == 1
12884      {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
12885       &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12886      // J1 == J2 == 1
12887      {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
12888       &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12889      {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
12890       &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12891      // for example, "bx lr"
12892      {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
12893       &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12894      // bxj
12895      {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
12896       &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12897      // compare and branch
12898      {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
12899       &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12900      // table branch byte
12901      {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12902       &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12903      // table branch halfword
12904      {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12905       &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12906
12907      //----------------------------------------------------------------------
12908      // Data-processing instructions
12909      //----------------------------------------------------------------------
12910      // adc (immediate)
12911      {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12912       &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12913      // adc (register)
12914      {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
12915       &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12916      {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12917       &EmulateInstructionARM::EmulateADCReg,
12918       "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12919      // add (register)
12920      {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
12921       &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12922      // Make sure "add sp, <Rm>" comes before this instruction, so there's no
12923      // ambiguity decoding the two.
12924      {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
12925       &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12926      // adr
12927      {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
12928       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12929      {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12930       &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12931      {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
12932       &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12933      // and (immediate)
12934      {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12935       &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12936      // and (register)
12937      {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
12938       &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12939      {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12940       &EmulateInstructionARM::EmulateANDReg,
12941       "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12942      // bic (immediate)
12943      {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12944       &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12945      // bic (register)
12946      {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
12947       &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12948      {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12949       &EmulateInstructionARM::EmulateBICReg,
12950       "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12951      // eor (immediate)
12952      {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12953       &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12954      // eor (register)
12955      {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
12956       &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12957      {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12958       &EmulateInstructionARM::EmulateEORReg,
12959       "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12960      // orr (immediate)
12961      {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12962       &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12963      // orr (register)
12964      {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
12965       &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12966      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12967       &EmulateInstructionARM::EmulateORRReg,
12968       "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12969      // rsb (immediate)
12970      {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
12971       &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12972      {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12973       &EmulateInstructionARM::EmulateRSBImm,
12974       "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12975      // rsb (register)
12976      {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12977       &EmulateInstructionARM::EmulateRSBReg,
12978       "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12979      // sbc (immediate)
12980      {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
12981       &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12982      // sbc (register)
12983      {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
12984       &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12985      {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
12986       &EmulateInstructionARM::EmulateSBCReg,
12987       "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12988      // add (immediate, Thumb)
12989      {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
12990       &EmulateInstructionARM::EmulateADDImmThumb,
12991       "adds|add<c> <Rd>,<Rn>,#<imm3>"},
12992      {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
12993       &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
12994      {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
12995       &EmulateInstructionARM::EmulateADDImmThumb,
12996       "add{s}<c>.w <Rd>,<Rn>,#<const>"},
12997      {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
12998       &EmulateInstructionARM::EmulateADDImmThumb,
12999       "addw<c> <Rd>,<Rn>,#<imm12>"},
13000      // sub (immediate, Thumb)
13001      {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
13002       &EmulateInstructionARM::EmulateSUBImmThumb,
13003       "subs|sub<c> <Rd>, <Rn> #imm3"},
13004      {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
13005       &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
13006      {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13007       &EmulateInstructionARM::EmulateSUBImmThumb,
13008       "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
13009      {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13010       &EmulateInstructionARM::EmulateSUBImmThumb,
13011       "subw<c> <Rd>, <Rn>, #imm12"},
13012      // sub (sp minus immediate)
13013      {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13014       &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
13015      {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13016       &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
13017      // sub (register)
13018      {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13019       &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
13020      {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13021       &EmulateInstructionARM::EmulateSUBReg,
13022       "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
13023      // teq (immediate)
13024      {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13025       &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
13026      // teq (register)
13027      {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13028       &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
13029      // tst (immediate)
13030      {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13031       &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
13032      // tst (register)
13033      {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
13034       &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
13035      {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13036       &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
13037
13038      // move from high register to high register
13039      {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
13040       &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
13041      // move from low register to low register
13042      {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
13043       &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
13044      // mov{s}<c>.w <Rd>, <Rm>
13045      {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13046       &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
13047      // move immediate
13048      {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13049       &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
13050      {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13051       &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
13052      {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13053       &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
13054      // mvn (immediate)
13055      {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13056       &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
13057      // mvn (register)
13058      {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13059       &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
13060      {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13061       &EmulateInstructionARM::EmulateMVNReg,
13062       "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
13063      // cmn (immediate)
13064      {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13065       &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
13066      // cmn (register)
13067      {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13068       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
13069      {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13070       &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
13071      // cmp (immediate)
13072      {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13073       &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
13074      {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13075       &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
13076      // cmp (register) (Rn and Rm both from r0-r7)
13077      {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
13078       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13079      // cmp (register) (Rn and Rm not both from r0-r7)
13080      {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
13081       &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
13082      {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
13083       &EmulateInstructionARM::EmulateCMPReg,
13084       "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
13085      // asr (immediate)
13086      {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13087       &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
13088      {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13089       &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
13090      // asr (register)
13091      {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
13092       &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
13093      {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13094       &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13095      // lsl (immediate)
13096      {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
13097       &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
13098      {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13099       &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
13100      // lsl (register)
13101      {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
13102       &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
13103      {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13104       &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
13105      // lsr (immediate)
13106      {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
13107       &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
13108      {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13109       &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
13110      // lsr (register)
13111      {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13112       &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
13113      {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13114       &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
13115      // rrx is a special case encoding of ror (immediate)
13116      {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13117       &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
13118      // ror (immediate)
13119      {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13120       &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
13121      // ror (register)
13122      {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
13123       &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
13124      {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13125       &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
13126      // mul
13127      {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13128       &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
13129      // mul
13130      {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13131       &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
13132
13133      // subs pc, lr and related instructions
13134      {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13135       &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
13136
13137      //----------------------------------------------------------------------
13138      // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
13139      // LDM.. Instructions in this table;
13140      // otherwise the wrong instructions will be selected.
13141      //----------------------------------------------------------------------
13142
13143      {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13144       &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
13145      {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13146       &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
13147
13148      //----------------------------------------------------------------------
13149      // Load instructions
13150      //----------------------------------------------------------------------
13151      {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13152       &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
13153      {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13154       &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
13155      {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13156       &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
13157      {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13158       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
13159      {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13160       &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
13161      {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13162       &EmulateInstructionARM::EmulateLDRRtRnImm,
13163       "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
13164      {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13165       &EmulateInstructionARM::EmulateLDRRtRnImm,
13166       "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
13167      // Thumb2 PC-relative load into register
13168      {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13169       &EmulateInstructionARM::EmulateLDRRtPCRelative,
13170       "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
13171      {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13172       &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
13173      {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13174       &EmulateInstructionARM::EmulateLDRRegister,
13175       "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
13176      {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13177       &EmulateInstructionARM::EmulateLDRBImmediate,
13178       "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
13179      {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13180       &EmulateInstructionARM::EmulateLDRBImmediate,
13181       "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13182      {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13183       &EmulateInstructionARM::EmulateLDRBImmediate,
13184       "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
13185      {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13186       &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
13187      {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
13188       &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
13189      {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13190       &EmulateInstructionARM::EmulateLDRBRegister,
13191       "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13192      {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13193       &EmulateInstructionARM::EmulateLDRHImmediate,
13194       "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
13195      {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13196       &EmulateInstructionARM::EmulateLDRHImmediate,
13197       "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
13198      {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13199       &EmulateInstructionARM::EmulateLDRHImmediate,
13200       "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
13201      {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13202       &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
13203      {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13204       &EmulateInstructionARM::EmulateLDRHRegister,
13205       "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
13206      {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13207       &EmulateInstructionARM::EmulateLDRHRegister,
13208       "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13209      {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13210       &EmulateInstructionARM::EmulateLDRSBImmediate,
13211       "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
13212      {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13213       &EmulateInstructionARM::EmulateLDRSBImmediate,
13214       "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13215      {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13216       &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
13217      {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13218       &EmulateInstructionARM::EmulateLDRSBRegister,
13219       "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
13220      {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13221       &EmulateInstructionARM::EmulateLDRSBRegister,
13222       "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
13223      {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13224       &EmulateInstructionARM::EmulateLDRSHImmediate,
13225       "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
13226      {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13227       &EmulateInstructionARM::EmulateLDRSHImmediate,
13228       "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
13229      {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13230       &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
13231      {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13232       &EmulateInstructionARM::EmulateLDRSHRegister,
13233       "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
13234      {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13235       &EmulateInstructionARM::EmulateLDRSHRegister,
13236       "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13237      {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13238       &EmulateInstructionARM::EmulateLDRDImmediate,
13239       "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
13240      {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13241       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13242      {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13243       &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
13244      {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13245       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13246      {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13247       &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
13248      {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13249       &EmulateInstructionARM::EmulateVLD1Multiple,
13250       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13251      {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13252       &EmulateInstructionARM::EmulateVLD1Single,
13253       "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
13254      {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13255       &EmulateInstructionARM::EmulateVLD1SingleAll,
13256       "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13257
13258      //----------------------------------------------------------------------
13259      // Store instructions
13260      //----------------------------------------------------------------------
13261      {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13262       &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
13263      {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13264       &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
13265      {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13266       &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
13267      {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13268       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
13269      {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
13270       &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
13271      {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13272       &EmulateInstructionARM::EmulateSTRThumb,
13273       "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
13274      {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
13275       &EmulateInstructionARM::EmulateSTRThumb,
13276       "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
13277      {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13278       &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
13279      {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13280       &EmulateInstructionARM::EmulateSTRRegister,
13281       "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
13282      {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13283       &EmulateInstructionARM::EmulateSTRBThumb,
13284       "strb<c> <Rt>, [<Rn>, #<imm5>]"},
13285      {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13286       &EmulateInstructionARM::EmulateSTRBThumb,
13287       "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
13288      {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
13289       &EmulateInstructionARM::EmulateSTRBThumb,
13290       "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
13291      {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
13292       &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
13293      {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13294       &EmulateInstructionARM::EmulateSTRHRegister,
13295       "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
13296      {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13297       &EmulateInstructionARM::EmulateSTREX,
13298       "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
13299      {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
13300       &EmulateInstructionARM::EmulateSTRDImm,
13301       "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
13302      {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13303       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13304      {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13305       &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
13306      {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
13307       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
13308      {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
13309       &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
13310      {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13311       &EmulateInstructionARM::EmulateVST1Multiple,
13312       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13313      {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
13314       &EmulateInstructionARM::EmulateVST1Single,
13315       "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
13316
13317      //----------------------------------------------------------------------
13318      // Other instructions
13319      //----------------------------------------------------------------------
13320      {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13321       &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
13322      {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
13323       &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13324      {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13325       &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
13326      {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13327       &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13328      {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13329       &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
13330      {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13331       &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
13332      {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
13333       &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
13334      {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
13335       &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
13336  };
13337
13338  const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
13339  for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
13340    if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
13341        (g_thumb_opcodes[i].variants & arm_isa) != 0)
13342      return &g_thumb_opcodes[i];
13343  }
13344  return NULL;
13345}
13346
13347bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
13348  m_arch = arch;
13349  m_arm_isa = 0;
13350  const char *arch_cstr = arch.GetArchitectureName();
13351  if (arch_cstr) {
13352    if (0 == ::strcasecmp(arch_cstr, "armv4t"))
13353      m_arm_isa = ARMv4T;
13354    else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
13355      m_arm_isa = ARMv5TEJ;
13356    else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
13357      m_arm_isa = ARMv5TE;
13358    else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
13359      m_arm_isa = ARMv5T;
13360    else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
13361      m_arm_isa = ARMv6K;
13362    else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
13363      m_arm_isa = ARMv6T2;
13364    else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
13365      m_arm_isa = ARMv7S;
13366    else if (0 == ::strcasecmp(arch_cstr, "arm"))
13367      m_arm_isa = ARMvAll;
13368    else if (0 == ::strcasecmp(arch_cstr, "thumb"))
13369      m_arm_isa = ARMvAll;
13370    else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
13371      m_arm_isa = ARMv4;
13372    else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
13373      m_arm_isa = ARMv6;
13374    else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
13375      m_arm_isa = ARMv7;
13376    else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
13377      m_arm_isa = ARMv8;
13378  }
13379  return m_arm_isa != 0;
13380}
13381
13382bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
13383                                           const Address &inst_addr,
13384                                           Target *target) {
13385  if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
13386    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
13387        m_arch.IsAlwaysThumbInstructions())
13388      m_opcode_mode = eModeThumb;
13389    else {
13390      AddressClass addr_class = inst_addr.GetAddressClass();
13391
13392      if ((addr_class == eAddressClassCode) ||
13393          (addr_class == eAddressClassUnknown))
13394        m_opcode_mode = eModeARM;
13395      else if (addr_class == eAddressClassCodeAlternateISA)
13396        m_opcode_mode = eModeThumb;
13397      else
13398        return false;
13399    }
13400    if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
13401      m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13402    else
13403      m_opcode_cpsr = CPSR_MODE_USR;
13404    return true;
13405  }
13406  return false;
13407}
13408
13409bool EmulateInstructionARM::ReadInstruction() {
13410  bool success = false;
13411  m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
13412                                       LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13413  if (success) {
13414    addr_t pc =
13415        ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
13416                             LLDB_INVALID_ADDRESS, &success);
13417    if (success) {
13418      Context read_inst_context;
13419      read_inst_context.type = eContextReadOpcode;
13420      read_inst_context.SetNoArgs();
13421
13422      if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
13423        m_opcode_mode = eModeThumb;
13424        uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13425
13426        if (success) {
13427          if ((thumb_opcode & 0xe000) != 0xe000 ||
13428              ((thumb_opcode & 0x1800u) == 0)) {
13429            m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
13430          } else {
13431            m_opcode.SetOpcode32(
13432                (thumb_opcode << 16) |
13433                    MemARead(read_inst_context, pc + 2, 2, 0, &success),
13434                GetByteOrder());
13435          }
13436        }
13437      } else {
13438        m_opcode_mode = eModeARM;
13439        m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
13440                             GetByteOrder());
13441      }
13442
13443      if (!m_ignore_conditions) {
13444        // If we are not ignoreing the conditions then init the it session from
13445        // the current
13446        // value of cpsr.
13447        uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
13448                      Bits32(m_opcode_cpsr, 26, 25);
13449        if (it != 0)
13450          m_it_session.InitIT(it);
13451      }
13452    }
13453  }
13454  if (!success) {
13455    m_opcode_mode = eModeInvalid;
13456    m_addr = LLDB_INVALID_ADDRESS;
13457  }
13458  return success;
13459}
13460
13461uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
13462
13463bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
13464  // If we are ignoring conditions, then always return true.
13465  // this allows us to iterate over disassembly code and still
13466  // emulate an instruction even if we don't have all the right
13467  // bits set in the CPSR register...
13468  if (m_ignore_conditions)
13469    return true;
13470
13471  const uint32_t cond = CurrentCond(opcode);
13472  if (cond == UINT32_MAX)
13473    return false;
13474
13475  bool result = false;
13476  switch (UnsignedBits(cond, 3, 1)) {
13477  case 0:
13478    if (m_opcode_cpsr == 0)
13479      result = true;
13480    else
13481      result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13482    break;
13483  case 1:
13484    if (m_opcode_cpsr == 0)
13485      result = true;
13486    else
13487      result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13488    break;
13489  case 2:
13490    if (m_opcode_cpsr == 0)
13491      result = true;
13492    else
13493      result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13494    break;
13495  case 3:
13496    if (m_opcode_cpsr == 0)
13497      result = true;
13498    else
13499      result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13500    break;
13501  case 4:
13502    if (m_opcode_cpsr == 0)
13503      result = true;
13504    else
13505      result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
13506               ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13507    break;
13508  case 5:
13509    if (m_opcode_cpsr == 0)
13510      result = true;
13511    else {
13512      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13513      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13514      result = n == v;
13515    }
13516    break;
13517  case 6:
13518    if (m_opcode_cpsr == 0)
13519      result = true;
13520    else {
13521      bool n = (m_opcode_cpsr & MASK_CPSR_N);
13522      bool v = (m_opcode_cpsr & MASK_CPSR_V);
13523      result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13524    }
13525    break;
13526  case 7:
13527    // Always execute (cond == 0b1110, or the special 0b1111 which gives
13528    // opcodes different meanings, but always means execution happens.
13529    return true;
13530  }
13531
13532  if (cond & 1)
13533    result = !result;
13534  return result;
13535}
13536
13537uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
13538  switch (m_opcode_mode) {
13539  case eModeInvalid:
13540    break;
13541
13542  case eModeARM:
13543    return UnsignedBits(opcode, 31, 28);
13544
13545  case eModeThumb:
13546    // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13547    // 'cond' field of the encoding.
13548    {
13549      const uint32_t byte_size = m_opcode.GetByteSize();
13550      if (byte_size == 2) {
13551        if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13552          return Bits32(opcode, 11, 8);
13553      } else if (byte_size == 4) {
13554        if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
13555            Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
13556          return Bits32(opcode, 25, 22);
13557        }
13558      } else
13559        // We have an invalid thumb instruction, let's bail out.
13560        break;
13561
13562      return m_it_session.GetCond();
13563    }
13564  }
13565  return UINT32_MAX; // Return invalid value
13566}
13567
13568bool EmulateInstructionARM::InITBlock() {
13569  return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13570}
13571
13572bool EmulateInstructionARM::LastInITBlock() {
13573  return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13574}
13575
13576bool EmulateInstructionARM::BadMode(uint32_t mode) {
13577
13578  switch (mode) {
13579  case 16:
13580    return false; // '10000'
13581  case 17:
13582    return false; // '10001'
13583  case 18:
13584    return false; // '10010'
13585  case 19:
13586    return false; // '10011'
13587  case 22:
13588    return false; // '10110'
13589  case 23:
13590    return false; // '10111'
13591  case 27:
13592    return false; // '11011'
13593  case 31:
13594    return false; // '11111'
13595  default:
13596    return true;
13597  }
13598  return true;
13599}
13600
13601bool EmulateInstructionARM::CurrentModeIsPrivileged() {
13602  uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
13603
13604  if (BadMode(mode))
13605    return false;
13606
13607  if (mode == 16)
13608    return false;
13609
13610  return true;
13611}
13612
13613void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
13614                                             bool affect_execstate) {
13615  bool privileged = CurrentModeIsPrivileged();
13616
13617  uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
13618
13619  if (BitIsSet(bytemask, 3)) {
13620    tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
13621    if (affect_execstate)
13622      tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
13623  }
13624
13625  if (BitIsSet(bytemask, 2)) {
13626    tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
13627  }
13628
13629  if (BitIsSet(bytemask, 1)) {
13630    if (affect_execstate)
13631      tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
13632    tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
13633    if (privileged)
13634      tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
13635  }
13636
13637  if (BitIsSet(bytemask, 0)) {
13638    if (privileged)
13639      tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
13640    if (affect_execstate)
13641      tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
13642    if (privileged)
13643      tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
13644  }
13645
13646  m_opcode_cpsr = tmp_cpsr;
13647}
13648
13649bool EmulateInstructionARM::BranchWritePC(const Context &context,
13650                                          uint32_t addr) {
13651  addr_t target;
13652
13653  // Check the current instruction set.
13654  if (CurrentInstrSet() == eModeARM)
13655    target = addr & 0xfffffffc;
13656  else
13657    target = addr & 0xfffffffe;
13658
13659  if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
13660                             LLDB_REGNUM_GENERIC_PC, target))
13661    return false;
13662
13663  return true;
13664}
13665
13666// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
13667// inspecting addr.
13668bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
13669  addr_t target;
13670  // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13671  // we want to record it and issue a WriteRegister callback so the clients
13672  // can track the mode changes accordingly.
13673  bool cpsr_changed = false;
13674
13675  if (BitIsSet(addr, 0)) {
13676    if (CurrentInstrSet() != eModeThumb) {
13677      SelectInstrSet(eModeThumb);
13678      cpsr_changed = true;
13679    }
13680    target = addr & 0xfffffffe;
13681    context.SetISA(eModeThumb);
13682  } else if (BitIsClear(addr, 1)) {
13683    if (CurrentInstrSet() != eModeARM) {
13684      SelectInstrSet(eModeARM);
13685      cpsr_changed = true;
13686    }
13687    target = addr & 0xfffffffc;
13688    context.SetISA(eModeARM);
13689  } else
13690    return false; // address<1:0> == '10' => UNPREDICTABLE
13691
13692  if (cpsr_changed) {
13693    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
13694                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13695      return false;
13696  }
13697  if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
13698                             LLDB_REGNUM_GENERIC_PC, target))
13699    return false;
13700
13701  return true;
13702}
13703
13704// Dispatches to either BXWritePC or BranchWritePC based on architecture
13705// versions.
13706bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
13707  if (ArchVersion() >= ARMv5T)
13708    return BXWritePC(context, addr);
13709  else
13710    return BranchWritePC((const Context)context, addr);
13711}
13712
13713// Dispatches to either BXWritePC or BranchWritePC based on architecture
13714// versions and current instruction set.
13715bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
13716  if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13717    return BXWritePC(context, addr);
13718  else
13719    return BranchWritePC((const Context)context, addr);
13720}
13721
13722EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
13723  return m_opcode_mode;
13724}
13725
13726// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13727// ReadInstruction() is performed.  This function has a side effect of updating
13728// the m_new_inst_cpsr member variable if necessary.
13729bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
13730  m_new_inst_cpsr = m_opcode_cpsr;
13731  switch (arm_or_thumb) {
13732  default:
13733    return false;
13734  case eModeARM:
13735    // Clear the T bit.
13736    m_new_inst_cpsr &= ~MASK_CPSR_T;
13737    break;
13738  case eModeThumb:
13739    // Set the T bit.
13740    m_new_inst_cpsr |= MASK_CPSR_T;
13741    break;
13742  }
13743  return true;
13744}
13745
13746// This function returns TRUE if the processor currently provides support for
13747// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13748// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13749bool EmulateInstructionARM::UnalignedSupport() {
13750  return (ArchVersion() >= ARMv7);
13751}
13752
13753// The main addition and subtraction instructions can produce status information
13754// about both unsigned carry and signed overflow conditions.  This status
13755// information can be used to synthesize multi-word additions and subtractions.
13756EmulateInstructionARM::AddWithCarryResult
13757EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
13758  uint32_t result;
13759  uint8_t carry_out;
13760  uint8_t overflow;
13761
13762  uint64_t unsigned_sum = x + y + carry_in;
13763  int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13764
13765  result = UnsignedBits(unsigned_sum, 31, 0);
13766  //    carry_out = (result == unsigned_sum ? 0 : 1);
13767  overflow = ((int32_t)result == signed_sum ? 0 : 1);
13768
13769  if (carry_in)
13770    carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
13771  else
13772    carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
13773
13774  AddWithCarryResult res = {result, carry_out, overflow};
13775  return res;
13776}
13777
13778uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
13779  lldb::RegisterKind reg_kind;
13780  uint32_t reg_num;
13781  switch (num) {
13782  case SP_REG:
13783    reg_kind = eRegisterKindGeneric;
13784    reg_num = LLDB_REGNUM_GENERIC_SP;
13785    break;
13786  case LR_REG:
13787    reg_kind = eRegisterKindGeneric;
13788    reg_num = LLDB_REGNUM_GENERIC_RA;
13789    break;
13790  case PC_REG:
13791    reg_kind = eRegisterKindGeneric;
13792    reg_num = LLDB_REGNUM_GENERIC_PC;
13793    break;
13794  default:
13795    if (num < SP_REG) {
13796      reg_kind = eRegisterKindDWARF;
13797      reg_num = dwarf_r0 + num;
13798    } else {
13799      // assert(0 && "Invalid register number");
13800      *success = false;
13801      return UINT32_MAX;
13802    }
13803    break;
13804  }
13805
13806  // Read our register.
13807  uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
13808
13809  // When executing an ARM instruction , PC reads as the address of the current
13810  // instruction plus 8.
13811  // When executing a Thumb instruction , PC reads as the address of the current
13812  // instruction plus 4.
13813  if (num == 15) {
13814    if (CurrentInstrSet() == eModeARM)
13815      val += 8;
13816    else
13817      val += 4;
13818  }
13819
13820  return val;
13821}
13822
13823// Write the result to the ARM core register Rd, and optionally update the
13824// condition flags based on the result.
13825//
13826// This helper method tries to encapsulate the following pseudocode from the
13827// ARM Architecture Reference Manual:
13828//
13829// if d == 15 then         // Can only occur for encoding A1
13830//     ALUWritePC(result); // setflags is always FALSE here
13831// else
13832//     R[d] = result;
13833//     if setflags then
13834//         APSR.N = result<31>;
13835//         APSR.Z = IsZeroBit(result);
13836//         APSR.C = carry;
13837//         // APSR.V unchanged
13838//
13839// In the above case, the API client does not pass in the overflow arg, which
13840// defaults to ~0u.
13841bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
13842    Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
13843    const uint32_t carry, const uint32_t overflow) {
13844  if (Rd == 15) {
13845    if (!ALUWritePC(context, result))
13846      return false;
13847  } else {
13848    lldb::RegisterKind reg_kind;
13849    uint32_t reg_num;
13850    switch (Rd) {
13851    case SP_REG:
13852      reg_kind = eRegisterKindGeneric;
13853      reg_num = LLDB_REGNUM_GENERIC_SP;
13854      break;
13855    case LR_REG:
13856      reg_kind = eRegisterKindGeneric;
13857      reg_num = LLDB_REGNUM_GENERIC_RA;
13858      break;
13859    default:
13860      reg_kind = eRegisterKindDWARF;
13861      reg_num = dwarf_r0 + Rd;
13862    }
13863    if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
13864      return false;
13865    if (setflags)
13866      return WriteFlags(context, result, carry, overflow);
13867  }
13868  return true;
13869}
13870
13871// This helper method tries to encapsulate the following pseudocode from the
13872// ARM Architecture Reference Manual:
13873//
13874// APSR.N = result<31>;
13875// APSR.Z = IsZeroBit(result);
13876// APSR.C = carry;
13877// APSR.V = overflow
13878//
13879// Default arguments can be specified for carry and overflow parameters, which
13880// means
13881// not to update the respective flags.
13882bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
13883                                       const uint32_t carry,
13884                                       const uint32_t overflow) {
13885  m_new_inst_cpsr = m_opcode_cpsr;
13886  SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13887  SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13888  if (carry != ~0u)
13889    SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13890  if (overflow != ~0u)
13891    SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13892  if (m_new_inst_cpsr != m_opcode_cpsr) {
13893    if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
13894                               LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13895      return false;
13896  }
13897  return true;
13898}
13899
13900bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
13901  ARMOpcode *opcode_data = NULL;
13902
13903  if (m_opcode_mode == eModeThumb)
13904    opcode_data =
13905        GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
13906  else if (m_opcode_mode == eModeARM)
13907    opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
13908
13909  const bool auto_advance_pc =
13910      evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13911  m_ignore_conditions =
13912      evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13913
13914  bool success = false;
13915  if (m_opcode_cpsr == 0 || m_ignore_conditions == false) {
13916    m_opcode_cpsr =
13917        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
13918  }
13919
13920  // Only return false if we are unable to read the CPSR if we care about
13921  // conditions
13922  if (success == false && m_ignore_conditions == false)
13923    return false;
13924
13925  uint32_t orig_pc_value = 0;
13926  if (auto_advance_pc) {
13927    orig_pc_value =
13928        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
13929    if (!success)
13930      return false;
13931  }
13932
13933  // Call the Emulate... function if we managed to decode the opcode.
13934  if (opcode_data) {
13935    success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
13936                                             opcode_data->encoding);
13937    if (!success)
13938      return false;
13939  }
13940
13941  // Advance the ITSTATE bits to their values for the next instruction if we
13942  // haven't just executed
13943  // an IT instruction what initialized it.
13944  if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
13945      (opcode_data == nullptr ||
13946       opcode_data->callback != &EmulateInstructionARM::EmulateIT))
13947    m_it_session.ITAdvance();
13948
13949  if (auto_advance_pc) {
13950    uint32_t after_pc_value =
13951        ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
13952    if (!success)
13953      return false;
13954
13955    if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
13956      after_pc_value += m_opcode.GetByteSize();
13957
13958      EmulateInstruction::Context context;
13959      context.type = eContextAdvancePC;
13960      context.SetNoArgs();
13961      if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
13962                                 after_pc_value))
13963        return false;
13964    }
13965  }
13966  return true;
13967}
13968
13969EmulateInstruction::InstructionCondition
13970EmulateInstructionARM::GetInstructionCondition() {
13971  const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
13972  if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
13973    return EmulateInstruction::UnconditionalCondition;
13974  return cond;
13975}
13976
13977bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
13978                                          OptionValueDictionary *test_data) {
13979  if (!test_data) {
13980    out_stream->Printf("TestEmulation: Missing test data.\n");
13981    return false;
13982  }
13983
13984  static ConstString opcode_key("opcode");
13985  static ConstString before_key("before_state");
13986  static ConstString after_key("after_state");
13987
13988  OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
13989
13990  uint32_t test_opcode;
13991  if ((value_sp.get() == NULL) ||
13992      (value_sp->GetType() != OptionValue::eTypeUInt64)) {
13993    out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
13994    return false;
13995  }
13996  test_opcode = value_sp->GetUInt64Value();
13997
13998  if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
13999      arch.IsAlwaysThumbInstructions()) {
14000    m_opcode_mode = eModeThumb;
14001    if (test_opcode < 0x10000)
14002      m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
14003    else
14004      m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14005  } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
14006    m_opcode_mode = eModeARM;
14007    m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
14008  } else {
14009    out_stream->Printf("TestEmulation:  Invalid arch.\n");
14010    return false;
14011  }
14012
14013  EmulationStateARM before_state;
14014  EmulationStateARM after_state;
14015
14016  value_sp = test_data->GetValueForKey(before_key);
14017  if ((value_sp.get() == NULL) ||
14018      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14019    out_stream->Printf("TestEmulation:  Failed to find 'before' state.\n");
14020    return false;
14021  }
14022
14023  OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
14024  if (!before_state.LoadStateFromDictionary(state_dictionary)) {
14025    out_stream->Printf("TestEmulation:  Failed loading 'before' state.\n");
14026    return false;
14027  }
14028
14029  value_sp = test_data->GetValueForKey(after_key);
14030  if ((value_sp.get() == NULL) ||
14031      (value_sp->GetType() != OptionValue::eTypeDictionary)) {
14032    out_stream->Printf("TestEmulation:  Failed to find 'after' state.\n");
14033    return false;
14034  }
14035
14036  state_dictionary = value_sp->GetAsDictionary();
14037  if (!after_state.LoadStateFromDictionary(state_dictionary)) {
14038    out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
14039    return false;
14040  }
14041
14042  SetBaton((void *)&before_state);
14043  SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
14044               &EmulationStateARM::WritePseudoMemory,
14045               &EmulationStateARM::ReadPseudoRegister,
14046               &EmulationStateARM::WritePseudoRegister);
14047
14048  bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
14049  if (!success) {
14050    out_stream->Printf("TestEmulation:  EvaluateInstruction() failed.\n");
14051    return false;
14052  }
14053
14054  success = before_state.CompareState(after_state);
14055  if (!success)
14056    out_stream->Printf(
14057        "TestEmulation:  'before' and 'after' states do not match.\n");
14058
14059  return success;
14060}
14061//
14062//
14063// const char *
14064// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
14065//{
14066//    if (reg_kind == eRegisterKindGeneric)
14067//    {
14068//        switch (reg_num)
14069//        {
14070//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
14071//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
14072//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
14073//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
14074//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
14075//        default: return NULL;
14076//        }
14077//    }
14078//    else if (reg_kind == eRegisterKindDWARF)
14079//    {
14080//        return GetARMDWARFRegisterName (reg_num);
14081//    }
14082//    return NULL;
14083//}
14084//
14085bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
14086  unwind_plan.Clear();
14087  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
14088
14089  UnwindPlan::RowSP row(new UnwindPlan::Row);
14090
14091  // Our previous Call Frame Address is the stack pointer
14092  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
14093
14094  unwind_plan.AppendRow(row);
14095  unwind_plan.SetSourceName("EmulateInstructionARM");
14096  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
14097  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
14098  unwind_plan.SetReturnAddressRegister(dwarf_lr);
14099  return true;
14100}
14101