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/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Interpreter/OptionValueArray.h"
20 #include "lldb/Interpreter/OptionValueDictionary.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26 
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
29                                      // and countTrailingZeros function
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 // Convenient macro definitions.
35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
37 
38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
39 
40 //----------------------------------------------------------------------
41 //
42 // ITSession implementation
43 //
44 //----------------------------------------------------------------------
45 
46 // A8.6.50
47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
48 static uint32_t
49 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     {
54 #ifdef LLDB_CONFIGURATION_DEBUG
55         printf("Encoding error: IT Mask '0000'\n");
56 #endif
57         return 0;
58     }
59     return (4 - TZ);
60 }
61 
62 // Init ITState.  Note that at least one bit is always 1 in mask.
63 bool ITSession::InitIT(uint32_t bits7_0)
64 {
65     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
66     if (ITCounter == 0)
67         return false;
68 
69     // A8.6.50 IT
70     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
71     if (FirstCond == 0xF)
72     {
73 #ifdef LLDB_CONFIGURATION_DEBUG
74         printf("Encoding error: IT FirstCond '1111'\n");
75 #endif
76         return false;
77     }
78     if (FirstCond == 0xE && ITCounter != 1)
79     {
80 #ifdef LLDB_CONFIGURATION_DEBUG
81         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
82 #endif
83         return false;
84     }
85 
86     ITState = bits7_0;
87     return true;
88 }
89 
90 // Update ITState if necessary.
91 void ITSession::ITAdvance()
92 {
93     //assert(ITCounter);
94     --ITCounter;
95     if (ITCounter == 0)
96         ITState = 0;
97     else
98     {
99         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
100         SetBits32(ITState, 4, 0, NewITState4_0);
101     }
102 }
103 
104 // Return true if we're inside an IT Block.
105 bool ITSession::InITBlock()
106 {
107     return ITCounter != 0;
108 }
109 
110 // Return true if we're the last instruction inside an IT Block.
111 bool ITSession::LastInITBlock()
112 {
113     return ITCounter == 1;
114 }
115 
116 // Get condition bits for the current thumb instruction.
117 uint32_t ITSession::GetCond()
118 {
119     if (InITBlock())
120         return Bits32(ITState, 7, 4);
121     else
122         return COND_AL;
123 }
124 
125 // ARM constants used during decoding
126 #define REG_RD          0
127 #define LDM_REGLIST     1
128 #define SP_REG          13
129 #define LR_REG          14
130 #define PC_REG          15
131 #define PC_REGLIST_BIT  0x8000
132 
133 #define ARMv4     (1u << 0)
134 #define ARMv4T    (1u << 1)
135 #define ARMv5T    (1u << 2)
136 #define ARMv5TE   (1u << 3)
137 #define ARMv5TEJ  (1u << 4)
138 #define ARMv6     (1u << 5)
139 #define ARMv6K    (1u << 6)
140 #define ARMv6T2   (1u << 7)
141 #define ARMv7     (1u << 8)
142 #define ARMv7S    (1u << 9)
143 #define ARMv8     (1u << 10)
144 #define ARMvAll   (0xffffffffu)
145 
146 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
147 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
149 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
150 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
152 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
153 
154 #define No_VFP  0
155 #define VFPv1   (1u << 1)
156 #define VFPv2   (1u << 2)
157 #define VFPv3   (1u << 3)
158 #define AdvancedSIMD (1u << 4)
159 
160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
162 #define VFPv2v3     (VFPv2 | VFPv3)
163 
164 //----------------------------------------------------------------------
165 //
166 // EmulateInstructionARM implementation
167 //
168 //----------------------------------------------------------------------
169 
170 void
171 EmulateInstructionARM::Initialize ()
172 {
173     PluginManager::RegisterPlugin (GetPluginNameStatic (),
174                                    GetPluginDescriptionStatic (),
175                                    CreateInstance);
176 }
177 
178 void
179 EmulateInstructionARM::Terminate ()
180 {
181     PluginManager::UnregisterPlugin (CreateInstance);
182 }
183 
184 ConstString
185 EmulateInstructionARM::GetPluginNameStatic ()
186 {
187     static ConstString g_name("arm");
188     return g_name;
189 }
190 
191 const char *
192 EmulateInstructionARM::GetPluginDescriptionStatic ()
193 {
194     return "Emulate instructions for the ARM architecture.";
195 }
196 
197 EmulateInstruction *
198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
199 {
200     if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
201     {
202         if (arch.GetTriple().getArch() == llvm::Triple::arm)
203         {
204             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
205 
206             if (emulate_insn_ap.get())
207                 return emulate_insn_ap.release();
208         }
209         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
210         {
211             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
212 
213             if (emulate_insn_ap.get())
214                 return emulate_insn_ap.release();
215         }
216     }
217 
218     return NULL;
219 }
220 
221 bool
222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
223 {
224     if (arch.GetTriple().getArch () == llvm::Triple::arm)
225         return true;
226     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
227         return true;
228 
229     return false;
230 }
231 
232 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
233 bool
234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
235 {
236     EmulateInstruction::Context context;
237     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
238     context.SetNoArgs ();
239 
240     uint32_t random_data = rand ();
241     const uint32_t addr_byte_size = GetAddressByteSize();
242 
243     if (!MemAWrite (context, address, random_data, addr_byte_size))
244         return false;
245 
246     return true;
247 }
248 
249 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
250 bool
251 EmulateInstructionARM::WriteBits32Unknown (int n)
252 {
253     EmulateInstruction::Context context;
254     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
255     context.SetNoArgs ();
256 
257     bool success;
258     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
259 
260     if (!success)
261         return false;
262 
263     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
264         return false;
265 
266     return true;
267 }
268 
269 bool
270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
271 {
272     if (reg_kind == eRegisterKindGeneric)
273     {
274         switch (reg_num)
275         {
276             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
277             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
278             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
279             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
280             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
281             default: return false;
282         }
283     }
284 
285     if (reg_kind == eRegisterKindDWARF)
286         return GetARMDWARFRegisterInfo(reg_num, reg_info);
287     return false;
288 }
289 
290 uint32_t
291 EmulateInstructionARM::GetFramePointerRegisterNumber () const
292 {
293     if (m_arch.GetTriple().isAndroid())
294         return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
295 
296     bool is_apple = false;
297     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
298         is_apple = true;
299     switch (m_arch.GetTriple().getOS())
300     {
301             case llvm::Triple::Darwin:
302             case llvm::Triple::MacOSX:
303             case llvm::Triple::IOS:
304                 is_apple = true;
305                 break;
306             default:
307                 break;
308     }
309 
310     /* On Apple iOS et al, the frame pointer register is always r7.
311      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
312      */
313 
314     uint32_t fp_regnum = 11;
315 
316     if (is_apple)
317         fp_regnum = 7;
318 
319     if (m_opcode_mode == eModeThumb)
320         fp_regnum = 7;
321 
322     return fp_regnum;
323 }
324 
325 uint32_t
326 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
327 {
328     bool is_apple = false;
329     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
330         is_apple = true;
331     switch (m_arch.GetTriple().getOS())
332     {
333             case llvm::Triple::Darwin:
334             case llvm::Triple::MacOSX:
335             case llvm::Triple::IOS:
336                 is_apple = true;
337                 break;
338             default:
339                 break;
340     }
341 
342     /* On Apple iOS et al, the frame pointer register is always r7.
343      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
344      */
345 
346     uint32_t fp_regnum = dwarf_r11;
347 
348     if (is_apple)
349         fp_regnum = dwarf_r7;
350 
351     if (m_opcode_mode == eModeThumb)
352         fp_regnum = dwarf_r7;
353 
354     return fp_regnum;
355 }
356 
357 // Push Multiple Registers stores multiple registers to the stack, storing to
358 // consecutive memory locations ending just below the address in SP, and updates
359 // SP to point to the start of the stored data.
360 bool
361 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
362 {
363 #if 0
364     // ARM pseudo code...
365     if (ConditionPassed())
366     {
367         EncodingSpecificOperations();
368         NullCheckIfThumbEE(13);
369         address = SP - 4*BitCount(registers);
370 
371         for (i = 0 to 14)
372         {
373             if (registers<i> == '1')
374             {
375                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
376                     MemA[address,4] = bits(32) UNKNOWN;
377                 else
378                     MemA[address,4] = R[i];
379                 address = address + 4;
380             }
381         }
382 
383         if (registers<15> == '1') // Only possible for encoding A1 or A2
384             MemA[address,4] = PCStoreValue();
385 
386         SP = SP - 4*BitCount(registers);
387     }
388 #endif
389 
390     bool success = false;
391     if (ConditionPassed(opcode))
392     {
393         const uint32_t addr_byte_size = GetAddressByteSize();
394         const addr_t sp = ReadCoreReg (SP_REG, &success);
395         if (!success)
396             return false;
397         uint32_t registers = 0;
398         uint32_t Rt; // the source register
399         switch (encoding) {
400         case eEncodingT1:
401             registers = Bits32(opcode, 7, 0);
402             // The M bit represents LR.
403             if (Bit32(opcode, 8))
404                 registers |= (1u << 14);
405             // if BitCount(registers) < 1 then UNPREDICTABLE;
406             if (BitCount(registers) < 1)
407                 return false;
408             break;
409         case eEncodingT2:
410             // Ignore bits 15 & 13.
411             registers = Bits32(opcode, 15, 0) & ~0xa000;
412             // if BitCount(registers) < 2 then UNPREDICTABLE;
413             if (BitCount(registers) < 2)
414                 return false;
415             break;
416         case eEncodingT3:
417             Rt = Bits32(opcode, 15, 12);
418             // if BadReg(t) then UNPREDICTABLE;
419             if (BadReg(Rt))
420                 return false;
421             registers = (1u << Rt);
422             break;
423         case eEncodingA1:
424             registers = Bits32(opcode, 15, 0);
425             // Instead of return false, let's handle the following case as well,
426             // which amounts to pushing one reg onto the full descending stacks.
427             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
428             break;
429         case eEncodingA2:
430             Rt = Bits32(opcode, 15, 12);
431             // if t == 13 then UNPREDICTABLE;
432             if (Rt == dwarf_sp)
433                 return false;
434             registers = (1u << Rt);
435             break;
436         default:
437             return false;
438         }
439         addr_t sp_offset = addr_byte_size * BitCount (registers);
440         addr_t addr = sp - sp_offset;
441         uint32_t i;
442 
443         EmulateInstruction::Context context;
444         context.type = EmulateInstruction::eContextPushRegisterOnStack;
445         RegisterInfo reg_info;
446         RegisterInfo sp_reg;
447         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
448         for (i=0; i<15; ++i)
449         {
450             if (BitIsSet (registers, i))
451             {
452                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
453                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
454                 uint32_t reg_value = ReadCoreReg(i, &success);
455                 if (!success)
456                     return false;
457                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
458                     return false;
459                 addr += addr_byte_size;
460             }
461         }
462 
463         if (BitIsSet (registers, 15))
464         {
465             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
466             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
467             const uint32_t pc = ReadCoreReg(PC_REG, &success);
468             if (!success)
469                 return false;
470             if (!MemAWrite (context, addr, pc, addr_byte_size))
471                 return false;
472         }
473 
474         context.type = EmulateInstruction::eContextAdjustStackPointer;
475         context.SetImmediateSigned (-sp_offset);
476 
477         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
478             return false;
479     }
480     return true;
481 }
482 
483 // Pop Multiple Registers loads multiple registers from the stack, loading from
484 // consecutive memory locations staring at the address in SP, and updates
485 // SP to point just above the loaded data.
486 bool
487 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
488 {
489 #if 0
490     // ARM pseudo code...
491     if (ConditionPassed())
492     {
493         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
494         address = SP;
495         for i = 0 to 14
496             if registers<i> == '1' then
497                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
498         if registers<15> == '1' then
499             if UnalignedAllowed then
500                 LoadWritePC(MemU[address,4]);
501             else
502                 LoadWritePC(MemA[address,4]);
503         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
504         if registers<13> == '1' then SP = bits(32) UNKNOWN;
505     }
506 #endif
507 
508     bool success = false;
509 
510     if (ConditionPassed(opcode))
511     {
512         const uint32_t addr_byte_size = GetAddressByteSize();
513         const addr_t sp = ReadCoreReg (SP_REG, &success);
514         if (!success)
515             return false;
516         uint32_t registers = 0;
517         uint32_t Rt; // the destination register
518         switch (encoding) {
519         case eEncodingT1:
520             registers = Bits32(opcode, 7, 0);
521             // The P bit represents PC.
522             if (Bit32(opcode, 8))
523                 registers |= (1u << 15);
524             // if BitCount(registers) < 1 then UNPREDICTABLE;
525             if (BitCount(registers) < 1)
526                 return false;
527             break;
528         case eEncodingT2:
529             // Ignore bit 13.
530             registers = Bits32(opcode, 15, 0) & ~0x2000;
531             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
532             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
533                 return false;
534             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
535             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
536                 return false;
537             break;
538         case eEncodingT3:
539             Rt = Bits32(opcode, 15, 12);
540             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
541             if (Rt == 13)
542                 return false;
543             if (Rt == 15 && InITBlock() && !LastInITBlock())
544                 return false;
545             registers = (1u << Rt);
546             break;
547         case eEncodingA1:
548             registers = Bits32(opcode, 15, 0);
549             // Instead of return false, let's handle the following case as well,
550             // which amounts to popping one reg from the full descending stacks.
551             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
552 
553             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
554             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
555                 return false;
556             break;
557         case eEncodingA2:
558             Rt = Bits32(opcode, 15, 12);
559             // if t == 13 then UNPREDICTABLE;
560             if (Rt == dwarf_sp)
561                 return false;
562             registers = (1u << Rt);
563             break;
564         default:
565             return false;
566         }
567         addr_t sp_offset = addr_byte_size * BitCount (registers);
568         addr_t addr = sp;
569         uint32_t i, data;
570 
571         EmulateInstruction::Context context;
572         context.type = EmulateInstruction::eContextPopRegisterOffStack;
573 
574         RegisterInfo sp_reg;
575         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
576 
577         for (i=0; i<15; ++i)
578         {
579             if (BitIsSet (registers, i))
580             {
581                 context.SetAddress(addr);
582                 data = MemARead(context, addr, 4, 0, &success);
583                 if (!success)
584                     return false;
585                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
586                     return false;
587                 addr += addr_byte_size;
588             }
589         }
590 
591         if (BitIsSet (registers, 15))
592         {
593             context.SetRegisterPlusOffset (sp_reg, addr - sp);
594             data = MemARead(context, addr, 4, 0, &success);
595             if (!success)
596                 return false;
597             // In ARMv5T and above, this is an interworking branch.
598             if (!LoadWritePC(context, data))
599                 return false;
600             //addr += addr_byte_size;
601         }
602 
603         context.type = EmulateInstruction::eContextAdjustStackPointer;
604         context.SetImmediateSigned (sp_offset);
605 
606         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
607             return false;
608     }
609     return true;
610 }
611 
612 // Set r7 or ip to point to saved value residing within the stack.
613 // ADD (SP plus immediate)
614 bool
615 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
616 {
617 #if 0
618     // ARM pseudo code...
619     if (ConditionPassed())
620     {
621         EncodingSpecificOperations();
622         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
623         if d == 15 then
624            ALUWritePC(result); // setflags is always FALSE here
625         else
626             R[d] = result;
627             if setflags then
628                 APSR.N = result<31>;
629                 APSR.Z = IsZeroBit(result);
630                 APSR.C = carry;
631                 APSR.V = overflow;
632     }
633 #endif
634 
635     bool success = false;
636 
637     if (ConditionPassed(opcode))
638     {
639         const addr_t sp = ReadCoreReg (SP_REG, &success);
640         if (!success)
641             return false;
642         uint32_t Rd; // the destination register
643         uint32_t imm32;
644         switch (encoding) {
645         case eEncodingT1:
646             Rd = 7;
647             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
648             break;
649         case eEncodingA1:
650             Rd = Bits32(opcode, 15, 12);
651             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
652             break;
653         default:
654             return false;
655         }
656         addr_t sp_offset = imm32;
657         addr_t addr = sp + sp_offset; // a pointer to the stack area
658 
659         EmulateInstruction::Context context;
660         if (Rd == GetFramePointerRegisterNumber())
661             context.type = eContextSetFramePointer;
662         else
663             context.type = EmulateInstruction::eContextRegisterPlusOffset;
664         RegisterInfo sp_reg;
665         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
666         context.SetRegisterPlusOffset (sp_reg, sp_offset);
667 
668         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
669             return false;
670     }
671     return true;
672 }
673 
674 // Set r7 or ip to the current stack pointer.
675 // MOV (register)
676 bool
677 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
678 {
679 #if 0
680     // ARM pseudo code...
681     if (ConditionPassed())
682     {
683         EncodingSpecificOperations();
684         result = R[m];
685         if d == 15 then
686             ALUWritePC(result); // setflags is always FALSE here
687         else
688             R[d] = result;
689             if setflags then
690                 APSR.N = result<31>;
691                 APSR.Z = IsZeroBit(result);
692                 // APSR.C unchanged
693                 // APSR.V unchanged
694     }
695 #endif
696 
697     bool success = false;
698 
699     if (ConditionPassed(opcode))
700     {
701         const addr_t sp = ReadCoreReg (SP_REG, &success);
702         if (!success)
703             return false;
704         uint32_t Rd; // the destination register
705         switch (encoding) {
706         case eEncodingT1:
707             Rd = 7;
708             break;
709         case eEncodingA1:
710             Rd = 12;
711             break;
712         default:
713             return false;
714         }
715 
716         EmulateInstruction::Context context;
717         if (Rd == GetFramePointerRegisterNumber())
718             context.type = EmulateInstruction::eContextSetFramePointer;
719         else
720             context.type = EmulateInstruction::eContextRegisterPlusOffset;
721         RegisterInfo sp_reg;
722         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
723         context.SetRegisterPlusOffset (sp_reg, 0);
724 
725         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
726             return false;
727     }
728     return true;
729 }
730 
731 // Move from high register (r8-r15) to low register (r0-r7).
732 // MOV (register)
733 bool
734 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
735 {
736     return EmulateMOVRdRm (opcode, encoding);
737 }
738 
739 // Move from register to register.
740 // MOV (register)
741 bool
742 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
743 {
744 #if 0
745     // ARM pseudo code...
746     if (ConditionPassed())
747     {
748         EncodingSpecificOperations();
749         result = R[m];
750         if d == 15 then
751             ALUWritePC(result); // setflags is always FALSE here
752         else
753             R[d] = result;
754             if setflags then
755                 APSR.N = result<31>;
756                 APSR.Z = IsZeroBit(result);
757                 // APSR.C unchanged
758                 // APSR.V unchanged
759     }
760 #endif
761 
762     bool success = false;
763 
764     if (ConditionPassed(opcode))
765     {
766         uint32_t Rm; // the source register
767         uint32_t Rd; // the destination register
768         bool setflags;
769         switch (encoding) {
770         case eEncodingT1:
771             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
772             Rm = Bits32(opcode, 6, 3);
773             setflags = false;
774             if (Rd == 15 && InITBlock() && !LastInITBlock())
775                 return false;
776             break;
777         case eEncodingT2:
778             Rd = Bits32(opcode, 2, 0);
779             Rm = Bits32(opcode, 5, 3);
780             setflags = true;
781             if (InITBlock())
782                 return false;
783             break;
784         case eEncodingT3:
785             Rd = Bits32(opcode, 11, 8);
786             Rm = Bits32(opcode, 3, 0);
787             setflags = BitIsSet(opcode, 20);
788             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
789             if (setflags && (BadReg(Rd) || BadReg(Rm)))
790                 return false;
791             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
792             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
793                 return false;
794             break;
795         case eEncodingA1:
796             Rd = Bits32(opcode, 15, 12);
797             Rm = Bits32(opcode, 3, 0);
798             setflags = BitIsSet(opcode, 20);
799 
800             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
801             if (Rd == 15 && setflags)
802                 return EmulateSUBSPcLrEtc (opcode, encoding);
803             break;
804         default:
805             return false;
806         }
807         uint32_t result = ReadCoreReg(Rm, &success);
808         if (!success)
809             return false;
810 
811         // The context specifies that Rm is to be moved into Rd.
812         EmulateInstruction::Context context;
813         if (Rd == 13)
814             context.type = EmulateInstruction::eContextAdjustStackPointer;
815         else
816             context.type = EmulateInstruction::eContextRegisterPlusOffset;
817         RegisterInfo dwarf_reg;
818         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
819         context.SetRegisterPlusOffset (dwarf_reg, 0);
820 
821         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
822             return false;
823     }
824     return true;
825 }
826 
827 // Move (immediate) writes an immediate value to the destination register.  It
828 // can optionally update the condition flags based on the value.
829 // MOV (immediate)
830 bool
831 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
832 {
833 #if 0
834     // ARM pseudo code...
835     if (ConditionPassed())
836     {
837         EncodingSpecificOperations();
838         result = imm32;
839         if d == 15 then         // Can only occur for ARM encoding
840             ALUWritePC(result); // setflags is always FALSE here
841         else
842             R[d] = result;
843             if setflags then
844                 APSR.N = result<31>;
845                 APSR.Z = IsZeroBit(result);
846                 APSR.C = carry;
847                 // APSR.V unchanged
848     }
849 #endif
850 
851     if (ConditionPassed(opcode))
852     {
853         uint32_t Rd; // the destination register
854         uint32_t imm32; // the immediate value to be written to Rd
855         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
856                             // for setflags == false, this value is a don't care
857                             // initialized to 0 to silence the static analyzer
858         bool setflags;
859         switch (encoding) {
860             case eEncodingT1:
861                 Rd = Bits32(opcode, 10, 8);
862                 setflags = !InITBlock();
863                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
864                 carry = APSR_C;
865 
866                 break;
867 
868             case eEncodingT2:
869                 Rd = Bits32(opcode, 11, 8);
870                 setflags = BitIsSet(opcode, 20);
871                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
872                 if (BadReg(Rd))
873                   return false;
874 
875                 break;
876 
877             case eEncodingT3:
878             {
879                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
880                 Rd = Bits32 (opcode, 11, 8);
881                 setflags = false;
882                 uint32_t imm4 = Bits32 (opcode, 19, 16);
883                 uint32_t imm3 = Bits32 (opcode, 14, 12);
884                 uint32_t i = Bit32 (opcode, 26);
885                 uint32_t imm8 = Bits32 (opcode, 7, 0);
886                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
887 
888                 // if BadReg(d) then UNPREDICTABLE;
889                 if (BadReg (Rd))
890                     return false;
891             }
892                 break;
893 
894             case eEncodingA1:
895                 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
896                 Rd = Bits32 (opcode, 15, 12);
897                 setflags = BitIsSet (opcode, 20);
898                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
899 
900                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
901                 if ((Rd == 15) && setflags)
902                     return EmulateSUBSPcLrEtc (opcode, encoding);
903 
904                 break;
905 
906             case eEncodingA2:
907             {
908                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
909                 Rd = Bits32 (opcode, 15, 12);
910                 setflags = false;
911                 uint32_t imm4 = Bits32 (opcode, 19, 16);
912                 uint32_t imm12 = Bits32 (opcode, 11, 0);
913                 imm32 = (imm4 << 12) | imm12;
914 
915                 // if d == 15 then UNPREDICTABLE;
916                 if (Rd == 15)
917                     return false;
918             }
919                 break;
920 
921             default:
922                 return false;
923         }
924         uint32_t result = imm32;
925 
926         // The context specifies that an immediate is to be moved into Rd.
927         EmulateInstruction::Context context;
928         context.type = EmulateInstruction::eContextImmediate;
929         context.SetNoArgs ();
930 
931         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
932             return false;
933     }
934     return true;
935 }
936 
937 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
938 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
939 // unsigned values.
940 //
941 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
942 // limited to only a few forms of the instruction.
943 bool
944 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
945 {
946 #if 0
947     if ConditionPassed() then
948         EncodingSpecificOperations();
949         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
950         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
951         result = operand1 * operand2;
952         R[d] = result<31:0>;
953         if setflags then
954             APSR.N = result<31>;
955             APSR.Z = IsZeroBit(result);
956             if ArchVersion() == 4 then
957                 APSR.C = bit UNKNOWN;
958             // else APSR.C unchanged
959             // APSR.V always unchanged
960 #endif
961 
962     if (ConditionPassed(opcode))
963     {
964         uint32_t d;
965         uint32_t n;
966         uint32_t m;
967         bool setflags;
968 
969         // EncodingSpecificOperations();
970         switch (encoding)
971         {
972             case eEncodingT1:
973                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
974                 d = Bits32 (opcode, 2, 0);
975                 n = Bits32 (opcode, 5, 3);
976                 m = Bits32 (opcode, 2, 0);
977                 setflags = !InITBlock();
978 
979                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
980                 if ((ArchVersion() < ARMv6) && (d == n))
981                     return false;
982 
983                 break;
984 
985             case eEncodingT2:
986                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
987                 d = Bits32 (opcode, 11, 8);
988                 n = Bits32 (opcode, 19, 16);
989                 m = Bits32 (opcode, 3, 0);
990                 setflags = false;
991 
992                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
993                 if (BadReg (d) || BadReg (n) || BadReg (m))
994                     return false;
995 
996                 break;
997 
998             case eEncodingA1:
999                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1000                 d = Bits32 (opcode, 19, 16);
1001                 n = Bits32 (opcode, 3, 0);
1002                 m = Bits32 (opcode, 11, 8);
1003                 setflags = BitIsSet (opcode, 20);
1004 
1005                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1006                 if ((d == 15) ||  (n == 15) || (m == 15))
1007                     return false;
1008 
1009                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1010                 if ((ArchVersion() < ARMv6) && (d == n))
1011                     return false;
1012 
1013                 break;
1014 
1015             default:
1016                 return false;
1017         }
1018 
1019         bool success = false;
1020 
1021         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1022         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1023         if (!success)
1024             return false;
1025 
1026         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1027         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1028         if (!success)
1029             return false;
1030 
1031         // result = operand1 * operand2;
1032         uint64_t result = operand1 * operand2;
1033 
1034         // R[d] = result<31:0>;
1035         RegisterInfo op1_reg;
1036         RegisterInfo op2_reg;
1037         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1038         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1039 
1040         EmulateInstruction::Context context;
1041         context.type = eContextArithmetic;
1042         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1043 
1044         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1045             return false;
1046 
1047         // if setflags then
1048         if (setflags)
1049         {
1050             // APSR.N = result<31>;
1051             // APSR.Z = IsZeroBit(result);
1052             m_new_inst_cpsr = m_opcode_cpsr;
1053             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1054             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1055             if (m_new_inst_cpsr != m_opcode_cpsr)
1056             {
1057                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1058                     return false;
1059             }
1060 
1061             // if ArchVersion() == 4 then
1062                 // APSR.C = bit UNKNOWN;
1063         }
1064     }
1065     return true;
1066 }
1067 
1068 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1069 // It can optionally update the condition flags based on the value.
1070 bool
1071 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1072 {
1073 #if 0
1074     // ARM pseudo code...
1075     if (ConditionPassed())
1076     {
1077         EncodingSpecificOperations();
1078         result = NOT(imm32);
1079         if d == 15 then         // Can only occur for ARM encoding
1080             ALUWritePC(result); // setflags is always FALSE here
1081         else
1082             R[d] = result;
1083             if setflags then
1084                 APSR.N = result<31>;
1085                 APSR.Z = IsZeroBit(result);
1086                 APSR.C = carry;
1087                 // APSR.V unchanged
1088     }
1089 #endif
1090 
1091     if (ConditionPassed(opcode))
1092     {
1093         uint32_t Rd; // the destination register
1094         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1095         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1096         bool setflags;
1097         switch (encoding) {
1098         case eEncodingT1:
1099             Rd = Bits32(opcode, 11, 8);
1100             setflags = BitIsSet(opcode, 20);
1101             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1102             break;
1103         case eEncodingA1:
1104             Rd = Bits32(opcode, 15, 12);
1105             setflags = BitIsSet(opcode, 20);
1106             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1107 
1108             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1109             if (Rd == 15 && setflags)
1110                 return EmulateSUBSPcLrEtc (opcode, encoding);
1111             break;
1112         default:
1113             return false;
1114         }
1115         uint32_t result = ~imm32;
1116 
1117         // The context specifies that an immediate is to be moved into Rd.
1118         EmulateInstruction::Context context;
1119         context.type = EmulateInstruction::eContextImmediate;
1120         context.SetNoArgs ();
1121 
1122         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1123             return false;
1124     }
1125     return true;
1126 }
1127 
1128 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1129 // It can optionally update the condition flags based on the result.
1130 bool
1131 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1132 {
1133 #if 0
1134     // ARM pseudo code...
1135     if (ConditionPassed())
1136     {
1137         EncodingSpecificOperations();
1138         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1139         result = NOT(shifted);
1140         if d == 15 then         // Can only occur for ARM encoding
1141             ALUWritePC(result); // setflags is always FALSE here
1142         else
1143             R[d] = result;
1144             if setflags then
1145                 APSR.N = result<31>;
1146                 APSR.Z = IsZeroBit(result);
1147                 APSR.C = carry;
1148                 // APSR.V unchanged
1149     }
1150 #endif
1151 
1152     if (ConditionPassed(opcode))
1153     {
1154         uint32_t Rm; // the source register
1155         uint32_t Rd; // the destination register
1156         ARM_ShifterType shift_t;
1157         uint32_t shift_n; // the shift applied to the value read from Rm
1158         bool setflags;
1159         uint32_t carry; // the carry bit after the shift operation
1160         switch (encoding) {
1161         case eEncodingT1:
1162             Rd = Bits32(opcode, 2, 0);
1163             Rm = Bits32(opcode, 5, 3);
1164             setflags = !InITBlock();
1165             shift_t = SRType_LSL;
1166             shift_n = 0;
1167             if (InITBlock())
1168                 return false;
1169             break;
1170         case eEncodingT2:
1171             Rd = Bits32(opcode, 11, 8);
1172             Rm = Bits32(opcode, 3, 0);
1173             setflags = BitIsSet(opcode, 20);
1174             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1175             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1176             if (BadReg(Rd) || BadReg(Rm))
1177                 return false;
1178             break;
1179         case eEncodingA1:
1180             Rd = Bits32(opcode, 15, 12);
1181             Rm = Bits32(opcode, 3, 0);
1182             setflags = BitIsSet(opcode, 20);
1183             shift_n = DecodeImmShiftARM(opcode, shift_t);
1184             break;
1185         default:
1186             return false;
1187         }
1188         bool success = false;
1189         uint32_t value = ReadCoreReg(Rm, &success);
1190         if (!success)
1191             return false;
1192 
1193         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1194         if (!success)
1195             return false;
1196         uint32_t result = ~shifted;
1197 
1198         // The context specifies that an immediate is to be moved into Rd.
1199         EmulateInstruction::Context context;
1200         context.type = EmulateInstruction::eContextImmediate;
1201         context.SetNoArgs ();
1202 
1203         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1204             return false;
1205     }
1206     return true;
1207 }
1208 
1209 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1210 // LDR (literal)
1211 bool
1212 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1213 {
1214 #if 0
1215     // ARM pseudo code...
1216     if (ConditionPassed())
1217     {
1218         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1219         base = Align(PC,4);
1220         address = if add then (base + imm32) else (base - imm32);
1221         data = MemU[address,4];
1222         if t == 15 then
1223             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1224         elsif UnalignedSupport() || address<1:0> = '00' then
1225             R[t] = data;
1226         else // Can only apply before ARMv7
1227             if CurrentInstrSet() == InstrSet_ARM then
1228                 R[t] = ROR(data, 8*UInt(address<1:0>));
1229             else
1230                 R[t] = bits(32) UNKNOWN;
1231     }
1232 #endif
1233 
1234     if (ConditionPassed(opcode))
1235     {
1236         bool success = false;
1237         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1238         if (!success)
1239             return false;
1240 
1241         // PC relative immediate load context
1242         EmulateInstruction::Context context;
1243         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1244         RegisterInfo pc_reg;
1245         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1246         context.SetRegisterPlusOffset (pc_reg, 0);
1247 
1248         uint32_t Rt;    // the destination register
1249         uint32_t imm32; // immediate offset from the PC
1250         bool add;       // +imm32 or -imm32?
1251         addr_t base;    // the base address
1252         addr_t address; // the PC relative address
1253         uint32_t data;  // the literal data value from the PC relative load
1254         switch (encoding) {
1255         case eEncodingT1:
1256             Rt = Bits32(opcode, 10, 8);
1257             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1258             add = true;
1259             break;
1260         case eEncodingT2:
1261             Rt = Bits32(opcode, 15, 12);
1262             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1263             add = BitIsSet(opcode, 23);
1264             if (Rt == 15 && InITBlock() && !LastInITBlock())
1265                 return false;
1266             break;
1267         default:
1268             return false;
1269         }
1270 
1271         base = Align(pc, 4);
1272         if (add)
1273             address = base + imm32;
1274         else
1275             address = base - imm32;
1276 
1277         context.SetRegisterPlusOffset(pc_reg, address - base);
1278         data = MemURead(context, address, 4, 0, &success);
1279         if (!success)
1280             return false;
1281 
1282         if (Rt == 15)
1283         {
1284             if (Bits32(address, 1, 0) == 0)
1285             {
1286                 // In ARMv5T and above, this is an interworking branch.
1287                 if (!LoadWritePC(context, data))
1288                     return false;
1289             }
1290             else
1291                 return false;
1292         }
1293         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1294         {
1295             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1296                 return false;
1297         }
1298         else // We don't handle ARM for now.
1299             return false;
1300 
1301     }
1302     return true;
1303 }
1304 
1305 // An add operation to adjust the SP.
1306 // ADD (SP plus immediate)
1307 bool
1308 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1309 {
1310 #if 0
1311     // ARM pseudo code...
1312     if (ConditionPassed())
1313     {
1314         EncodingSpecificOperations();
1315         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1316         if d == 15 then // Can only occur for ARM encoding
1317             ALUWritePC(result); // setflags is always FALSE here
1318         else
1319             R[d] = result;
1320             if setflags then
1321                 APSR.N = result<31>;
1322                 APSR.Z = IsZeroBit(result);
1323                 APSR.C = carry;
1324                 APSR.V = overflow;
1325     }
1326 #endif
1327 
1328     bool success = false;
1329 
1330     if (ConditionPassed(opcode))
1331     {
1332         const addr_t sp = ReadCoreReg (SP_REG, &success);
1333         if (!success)
1334             return false;
1335         uint32_t imm32; // the immediate operand
1336         uint32_t d;
1337         bool setflags;
1338         switch (encoding)
1339         {
1340             case eEncodingT1:
1341                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1342                 d = Bits32 (opcode, 10, 8);
1343                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1344                 setflags = false;
1345                 break;
1346 
1347             case eEncodingT2:
1348                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1349                 d = 13;
1350                 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1351                 setflags = false;
1352                 break;
1353 
1354             case eEncodingT3:
1355                 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
1356                 d = Bits32 (opcode, 11, 8);
1357                 imm32 = ThumbExpandImm (opcode);
1358                 setflags = Bit32 (opcode, 20);
1359 
1360                 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1361                 if (d == 15 && setflags == 1)
1362                     return false; // CMN (immediate) not yet supported
1363 
1364                 // if d == 15 && S == "0" then UNPREDICTABLE;
1365                 if (d == 15 && setflags == 0)
1366                     return false;
1367                 break;
1368 
1369             case eEncodingT4:
1370                 {
1371                     // if Rn == '1111' then SEE ADR;
1372                     // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1373                     d = Bits32 (opcode, 11, 8);
1374                     setflags = false;
1375                     uint32_t i = Bit32 (opcode, 26);
1376                     uint32_t imm3 = Bits32 (opcode, 14, 12);
1377                     uint32_t imm8 = Bits32 (opcode, 7, 0);
1378                     imm32 = (i << 11) | (imm3 << 8) | imm8;
1379 
1380                     // if d == 15 then UNPREDICTABLE;
1381                     if (d == 15)
1382                         return false;
1383                 }
1384                 break;
1385 
1386             default:
1387                 return false;
1388         }
1389         // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1390         AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
1391 
1392         EmulateInstruction::Context context;
1393         if (d == 13)
1394             context.type = EmulateInstruction::eContextAdjustStackPointer;
1395         else
1396             context.type = EmulateInstruction::eContextRegisterPlusOffset;
1397 
1398         RegisterInfo sp_reg;
1399         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1400         context.SetRegisterPlusOffset (sp_reg, res.result - sp);
1401 
1402         if (d == 15)
1403         {
1404             if (!ALUWritePC (context, res.result))
1405                 return false;
1406         }
1407         else
1408         {
1409             // R[d] = result;
1410             // if setflags then
1411             //     APSR.N = result<31>;
1412             //     APSR.Z = IsZeroBit(result);
1413             //     APSR.C = carry;
1414             //     APSR.V = overflow;
1415             if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
1416                 return false;
1417         }
1418     }
1419     return true;
1420 }
1421 
1422 // An add operation to adjust the SP.
1423 // ADD (SP plus register)
1424 bool
1425 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1426 {
1427 #if 0
1428     // ARM pseudo code...
1429     if (ConditionPassed())
1430     {
1431         EncodingSpecificOperations();
1432         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1433         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1434         if d == 15 then
1435             ALUWritePC(result); // setflags is always FALSE here
1436         else
1437             R[d] = result;
1438             if setflags then
1439                 APSR.N = result<31>;
1440                 APSR.Z = IsZeroBit(result);
1441                 APSR.C = carry;
1442                 APSR.V = overflow;
1443     }
1444 #endif
1445 
1446     bool success = false;
1447 
1448     if (ConditionPassed(opcode))
1449     {
1450         const addr_t sp = ReadCoreReg (SP_REG, &success);
1451         if (!success)
1452             return false;
1453         uint32_t Rm; // the second operand
1454         switch (encoding) {
1455         case eEncodingT2:
1456             Rm = Bits32(opcode, 6, 3);
1457             break;
1458         default:
1459             return false;
1460         }
1461         int32_t reg_value = ReadCoreReg(Rm, &success);
1462         if (!success)
1463             return false;
1464 
1465         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1466 
1467         EmulateInstruction::Context context;
1468         context.type = eContextArithmetic;
1469         RegisterInfo sp_reg;
1470         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1471 
1472         RegisterInfo other_reg;
1473         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1474         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1475 
1476         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1477             return false;
1478     }
1479     return true;
1480 }
1481 
1482 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1483 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1484 // from Thumb to ARM.
1485 // BLX (immediate)
1486 bool
1487 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1488 {
1489 #if 0
1490     // ARM pseudo code...
1491     if (ConditionPassed())
1492     {
1493         EncodingSpecificOperations();
1494         if CurrentInstrSet() == InstrSet_ARM then
1495             LR = PC - 4;
1496         else
1497             LR = PC<31:1> : '1';
1498         if targetInstrSet == InstrSet_ARM then
1499             targetAddress = Align(PC,4) + imm32;
1500         else
1501             targetAddress = PC + imm32;
1502         SelectInstrSet(targetInstrSet);
1503         BranchWritePC(targetAddress);
1504     }
1505 #endif
1506 
1507     bool success = true;
1508 
1509     if (ConditionPassed(opcode))
1510     {
1511         EmulateInstruction::Context context;
1512         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1513         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1514         if (!success)
1515             return false;
1516         addr_t lr; // next instruction address
1517         addr_t target; // target address
1518         int32_t imm32; // PC-relative offset
1519         switch (encoding) {
1520         case eEncodingT1:
1521             {
1522             lr = pc | 1u; // return address
1523             uint32_t S = Bit32(opcode, 26);
1524             uint32_t imm10 = Bits32(opcode, 25, 16);
1525             uint32_t J1 = Bit32(opcode, 13);
1526             uint32_t J2 = Bit32(opcode, 11);
1527             uint32_t imm11 = Bits32(opcode, 10, 0);
1528             uint32_t I1 = !(J1 ^ S);
1529             uint32_t I2 = !(J2 ^ S);
1530             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1531             imm32 = llvm::SignExtend32<25>(imm25);
1532             target = pc + imm32;
1533             SelectInstrSet (eModeThumb);
1534             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1535             if (InITBlock() && !LastInITBlock())
1536                 return false;
1537             break;
1538             }
1539         case eEncodingT2:
1540             {
1541             lr = pc | 1u; // return address
1542             uint32_t S = Bit32(opcode, 26);
1543             uint32_t imm10H = Bits32(opcode, 25, 16);
1544             uint32_t J1 = Bit32(opcode, 13);
1545             uint32_t J2 = Bit32(opcode, 11);
1546             uint32_t imm10L = Bits32(opcode, 10, 1);
1547             uint32_t I1 = !(J1 ^ S);
1548             uint32_t I2 = !(J2 ^ S);
1549             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1550             imm32 = llvm::SignExtend32<25>(imm25);
1551             target = Align(pc, 4) + imm32;
1552             SelectInstrSet (eModeARM);
1553             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1554             if (InITBlock() && !LastInITBlock())
1555                 return false;
1556             break;
1557             }
1558         case eEncodingA1:
1559             lr = pc - 4; // return address
1560             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1561             target = Align(pc, 4) + imm32;
1562             SelectInstrSet (eModeARM);
1563             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1564             break;
1565         case eEncodingA2:
1566             lr = pc - 4; // return address
1567             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1568             target = pc + imm32;
1569             SelectInstrSet (eModeThumb);
1570             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1571             break;
1572         default:
1573             return false;
1574         }
1575         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1576             return false;
1577         if (!BranchWritePC(context, target))
1578             return false;
1579         if (m_opcode_cpsr != m_new_inst_cpsr)
1580             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1581                 return false;
1582     }
1583     return true;
1584 }
1585 
1586 // Branch with Link and Exchange (register) calls a subroutine at an address and
1587 // instruction set specified by a register.
1588 // BLX (register)
1589 bool
1590 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1591 {
1592 #if 0
1593     // ARM pseudo code...
1594     if (ConditionPassed())
1595     {
1596         EncodingSpecificOperations();
1597         target = R[m];
1598         if CurrentInstrSet() == InstrSet_ARM then
1599             next_instr_addr = PC - 4;
1600             LR = next_instr_addr;
1601         else
1602             next_instr_addr = PC - 2;
1603             LR = next_instr_addr<31:1> : '1';
1604         BXWritePC(target);
1605     }
1606 #endif
1607 
1608     bool success = false;
1609 
1610     if (ConditionPassed(opcode))
1611     {
1612         EmulateInstruction::Context context;
1613         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1614         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1615         addr_t lr; // next instruction address
1616         if (!success)
1617             return false;
1618         uint32_t Rm; // the register with the target address
1619         switch (encoding) {
1620         case eEncodingT1:
1621             lr = (pc - 2) | 1u; // return address
1622             Rm = Bits32(opcode, 6, 3);
1623             // if m == 15 then UNPREDICTABLE;
1624             if (Rm == 15)
1625                 return false;
1626             if (InITBlock() && !LastInITBlock())
1627                 return false;
1628             break;
1629         case eEncodingA1:
1630             lr = pc - 4; // return address
1631             Rm = Bits32(opcode, 3, 0);
1632             // if m == 15 then UNPREDICTABLE;
1633             if (Rm == 15)
1634                 return false;
1635             break;
1636         default:
1637             return false;
1638         }
1639         addr_t target = ReadCoreReg (Rm, &success);
1640         if (!success)
1641             return false;
1642         RegisterInfo dwarf_reg;
1643         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1644         context.SetRegister (dwarf_reg);
1645         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1646             return false;
1647         if (!BXWritePC(context, target))
1648             return false;
1649     }
1650     return true;
1651 }
1652 
1653 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1654 bool
1655 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1656 {
1657 #if 0
1658     // ARM pseudo code...
1659     if (ConditionPassed())
1660     {
1661         EncodingSpecificOperations();
1662         BXWritePC(R[m]);
1663     }
1664 #endif
1665 
1666     if (ConditionPassed(opcode))
1667     {
1668         EmulateInstruction::Context context;
1669         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1670         uint32_t Rm; // the register with the target address
1671         switch (encoding) {
1672         case eEncodingT1:
1673             Rm = Bits32(opcode, 6, 3);
1674             if (InITBlock() && !LastInITBlock())
1675                 return false;
1676             break;
1677         case eEncodingA1:
1678             Rm = Bits32(opcode, 3, 0);
1679             break;
1680         default:
1681             return false;
1682         }
1683         bool success = false;
1684         addr_t target = ReadCoreReg (Rm, &success);
1685         if (!success)
1686             return false;
1687 
1688         RegisterInfo dwarf_reg;
1689         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1690         context.SetRegister (dwarf_reg);
1691         if (!BXWritePC(context, target))
1692             return false;
1693     }
1694     return true;
1695 }
1696 
1697 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1698 // address and instruction set specified by a register as though it were a BX instruction.
1699 //
1700 // TODO: Emulate Jazelle architecture?
1701 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1702 bool
1703 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1704 {
1705 #if 0
1706     // ARM pseudo code...
1707     if (ConditionPassed())
1708     {
1709         EncodingSpecificOperations();
1710         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1711             BXWritePC(R[m]);
1712         else
1713             if JazelleAcceptsExecution() then
1714                 SwitchToJazelleExecution();
1715             else
1716                 SUBARCHITECTURE_DEFINED handler call;
1717     }
1718 #endif
1719 
1720     if (ConditionPassed(opcode))
1721     {
1722         EmulateInstruction::Context context;
1723         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1724         uint32_t Rm; // the register with the target address
1725         switch (encoding) {
1726         case eEncodingT1:
1727             Rm = Bits32(opcode, 19, 16);
1728             if (BadReg(Rm))
1729                 return false;
1730             if (InITBlock() && !LastInITBlock())
1731                 return false;
1732             break;
1733         case eEncodingA1:
1734             Rm = Bits32(opcode, 3, 0);
1735             if (Rm == 15)
1736                 return false;
1737             break;
1738         default:
1739             return false;
1740         }
1741         bool success = false;
1742         addr_t target = ReadCoreReg (Rm, &success);
1743         if (!success)
1744             return false;
1745 
1746         RegisterInfo dwarf_reg;
1747         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1748         context.SetRegister (dwarf_reg);
1749         if (!BXWritePC(context, target))
1750             return false;
1751     }
1752     return true;
1753 }
1754 
1755 // Set r7 to point to some ip offset.
1756 // SUB (immediate)
1757 bool
1758 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1759 {
1760 #if 0
1761     // ARM pseudo code...
1762     if (ConditionPassed())
1763     {
1764         EncodingSpecificOperations();
1765         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1766         if d == 15 then // Can only occur for ARM encoding
1767            ALUWritePC(result); // setflags is always FALSE here
1768         else
1769             R[d] = result;
1770             if setflags then
1771                 APSR.N = result<31>;
1772                 APSR.Z = IsZeroBit(result);
1773                 APSR.C = carry;
1774                 APSR.V = overflow;
1775     }
1776 #endif
1777 
1778     if (ConditionPassed(opcode))
1779     {
1780         bool success = false;
1781         const addr_t ip = ReadCoreReg (12, &success);
1782         if (!success)
1783             return false;
1784         uint32_t imm32;
1785         switch (encoding) {
1786         case eEncodingA1:
1787             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1788             break;
1789         default:
1790             return false;
1791         }
1792         addr_t ip_offset = imm32;
1793         addr_t addr = ip - ip_offset; // the adjusted ip value
1794 
1795         EmulateInstruction::Context context;
1796         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1797         RegisterInfo dwarf_reg;
1798         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1799         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1800 
1801         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1802             return false;
1803     }
1804     return true;
1805 }
1806 
1807 // Set ip to point to some stack offset.
1808 // SUB (SP minus immediate)
1809 bool
1810 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1811 {
1812 #if 0
1813     // ARM pseudo code...
1814     if (ConditionPassed())
1815     {
1816         EncodingSpecificOperations();
1817         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1818         if d == 15 then // Can only occur for ARM encoding
1819            ALUWritePC(result); // setflags is always FALSE here
1820         else
1821             R[d] = result;
1822             if setflags then
1823                 APSR.N = result<31>;
1824                 APSR.Z = IsZeroBit(result);
1825                 APSR.C = carry;
1826                 APSR.V = overflow;
1827     }
1828 #endif
1829 
1830     if (ConditionPassed(opcode))
1831     {
1832         bool success = false;
1833         const addr_t sp = ReadCoreReg (SP_REG, &success);
1834         if (!success)
1835             return false;
1836         uint32_t imm32;
1837         switch (encoding) {
1838         case eEncodingA1:
1839             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1840             break;
1841         default:
1842             return false;
1843         }
1844         addr_t sp_offset = imm32;
1845         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1846 
1847         EmulateInstruction::Context context;
1848         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1849         RegisterInfo dwarf_reg;
1850         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1851         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1852 
1853         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1854             return false;
1855     }
1856     return true;
1857 }
1858 
1859 // This instruction subtracts an immediate value from the SP value, and writes
1860 // the result to the destination register.
1861 //
1862 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1863 bool
1864 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1865 {
1866 #if 0
1867     // ARM pseudo code...
1868     if (ConditionPassed())
1869     {
1870         EncodingSpecificOperations();
1871         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1872         if d == 15 then        // Can only occur for ARM encoding
1873            ALUWritePC(result); // setflags is always FALSE here
1874         else
1875             R[d] = result;
1876             if setflags then
1877                 APSR.N = result<31>;
1878                 APSR.Z = IsZeroBit(result);
1879                 APSR.C = carry;
1880                 APSR.V = overflow;
1881     }
1882 #endif
1883 
1884     bool success = false;
1885     if (ConditionPassed(opcode))
1886     {
1887         const addr_t sp = ReadCoreReg (SP_REG, &success);
1888         if (!success)
1889             return false;
1890 
1891         uint32_t Rd;
1892         bool setflags;
1893         uint32_t imm32;
1894         switch (encoding) {
1895         case eEncodingT1:
1896             Rd = 13;
1897             setflags = false;
1898             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1899             break;
1900         case eEncodingT2:
1901             Rd = Bits32(opcode, 11, 8);
1902             setflags = BitIsSet(opcode, 20);
1903             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1904             if (Rd == 15 && setflags)
1905                 return EmulateCMPImm(opcode, eEncodingT2);
1906             if (Rd == 15 && !setflags)
1907                 return false;
1908             break;
1909         case eEncodingT3:
1910             Rd = Bits32(opcode, 11, 8);
1911             setflags = false;
1912             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1913             if (Rd == 15)
1914                 return false;
1915             break;
1916         case eEncodingA1:
1917             Rd = Bits32(opcode, 15, 12);
1918             setflags = BitIsSet(opcode, 20);
1919             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1920 
1921             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1922             if (Rd == 15 && setflags)
1923                 return EmulateSUBSPcLrEtc (opcode, encoding);
1924             break;
1925         default:
1926             return false;
1927         }
1928         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1929 
1930         EmulateInstruction::Context context;
1931         if (Rd == 13)
1932         {
1933             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1934                                      // value gets passed down to context.SetImmediateSigned.
1935             context.type = EmulateInstruction::eContextAdjustStackPointer;
1936             context.SetImmediateSigned (-imm64); // the stack pointer offset
1937         }
1938         else
1939         {
1940             context.type = EmulateInstruction::eContextImmediate;
1941             context.SetNoArgs ();
1942         }
1943 
1944         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1945             return false;
1946     }
1947     return true;
1948 }
1949 
1950 // A store operation to the stack that also updates the SP.
1951 bool
1952 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1953 {
1954 #if 0
1955     // ARM pseudo code...
1956     if (ConditionPassed())
1957     {
1958         EncodingSpecificOperations();
1959         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1960         address = if index then offset_addr else R[n];
1961         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1962         if wback then R[n] = offset_addr;
1963     }
1964 #endif
1965 
1966     bool success = false;
1967     if (ConditionPassed(opcode))
1968     {
1969         const uint32_t addr_byte_size = GetAddressByteSize();
1970         const addr_t sp = ReadCoreReg (SP_REG, &success);
1971         if (!success)
1972             return false;
1973         uint32_t Rt; // the source register
1974         uint32_t imm12;
1975         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1976 
1977         bool index;
1978         bool add;
1979         bool wback;
1980         switch (encoding) {
1981         case eEncodingA1:
1982             Rt = Bits32(opcode, 15, 12);
1983             imm12 = Bits32(opcode, 11, 0);
1984             Rn = Bits32 (opcode, 19, 16);
1985 
1986             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1987                 return false;
1988 
1989             index = BitIsSet (opcode, 24);
1990             add = BitIsSet (opcode, 23);
1991             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1992 
1993             if (wback && ((Rn == 15) || (Rn == Rt)))
1994                 return false;
1995             break;
1996         default:
1997             return false;
1998         }
1999         addr_t offset_addr;
2000         if (add)
2001             offset_addr = sp + imm12;
2002         else
2003             offset_addr = sp - imm12;
2004 
2005         addr_t addr;
2006         if (index)
2007             addr = offset_addr;
2008         else
2009             addr = sp;
2010 
2011         EmulateInstruction::Context context;
2012         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2013         RegisterInfo sp_reg;
2014         RegisterInfo dwarf_reg;
2015 
2016         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2017         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2018         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2019         if (Rt != 15)
2020         {
2021             uint32_t reg_value = ReadCoreReg(Rt, &success);
2022             if (!success)
2023                 return false;
2024             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
2025                 return false;
2026         }
2027         else
2028         {
2029             const uint32_t pc = ReadCoreReg(PC_REG, &success);
2030             if (!success)
2031                 return false;
2032             if (!MemUWrite (context, addr, pc, addr_byte_size))
2033                 return false;
2034         }
2035 
2036 
2037         if (wback)
2038         {
2039             context.type = EmulateInstruction::eContextAdjustStackPointer;
2040             context.SetImmediateSigned (addr - sp);
2041             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2042                 return false;
2043         }
2044     }
2045     return true;
2046 }
2047 
2048 // Vector Push stores multiple extension registers to the stack.
2049 // It also updates SP to point to the start of the stored data.
2050 bool
2051 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2052 {
2053 #if 0
2054     // ARM pseudo code...
2055     if (ConditionPassed())
2056     {
2057         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2058         address = SP - imm32;
2059         SP = SP - imm32;
2060         if single_regs then
2061             for r = 0 to regs-1
2062                 MemA[address,4] = S[d+r]; address = address+4;
2063         else
2064             for r = 0 to regs-1
2065                 // Store as two word-aligned words in the correct order for current endianness.
2066                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2067                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2068                 address = address+8;
2069     }
2070 #endif
2071 
2072     bool success = false;
2073     if (ConditionPassed(opcode))
2074     {
2075         const uint32_t addr_byte_size = GetAddressByteSize();
2076         const addr_t sp = ReadCoreReg (SP_REG, &success);
2077         if (!success)
2078             return false;
2079         bool single_regs;
2080         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2081         uint32_t imm32; // stack offset
2082         uint32_t regs;  // number of registers
2083         switch (encoding) {
2084         case eEncodingT1:
2085         case eEncodingA1:
2086             single_regs = false;
2087             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2088             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2089             // If UInt(imm8) is odd, see "FSTMX".
2090             regs = Bits32(opcode, 7, 0) / 2;
2091             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2092             if (regs == 0 || regs > 16 || (d + regs) > 32)
2093                 return false;
2094             break;
2095         case eEncodingT2:
2096         case eEncodingA2:
2097             single_regs = true;
2098             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2099             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2100             regs = Bits32(opcode, 7, 0);
2101             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2102             if (regs == 0 || regs > 16 || (d + regs) > 32)
2103                 return false;
2104             break;
2105         default:
2106             return false;
2107         }
2108         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2109         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2110         addr_t sp_offset = imm32;
2111         addr_t addr = sp - sp_offset;
2112         uint32_t i;
2113 
2114         EmulateInstruction::Context context;
2115         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2116 
2117         RegisterInfo dwarf_reg;
2118         RegisterInfo sp_reg;
2119         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2120         for (i=0; i<regs; ++i)
2121         {
2122             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2123             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2124             // uint64_t to accommodate 64-bit registers.
2125             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2126             if (!success)
2127                 return false;
2128             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2129                 return false;
2130             addr += reg_byte_size;
2131         }
2132 
2133         context.type = EmulateInstruction::eContextAdjustStackPointer;
2134         context.SetImmediateSigned (-sp_offset);
2135 
2136         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2137             return false;
2138     }
2139     return true;
2140 }
2141 
2142 // Vector Pop loads multiple extension registers from the stack.
2143 // It also updates SP to point just above the loaded data.
2144 bool
2145 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2146 {
2147 #if 0
2148     // ARM pseudo code...
2149     if (ConditionPassed())
2150     {
2151         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2152         address = SP;
2153         SP = SP + imm32;
2154         if single_regs then
2155             for r = 0 to regs-1
2156                 S[d+r] = MemA[address,4]; address = address+4;
2157         else
2158             for r = 0 to regs-1
2159                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2160                 // Combine the word-aligned words in the correct order for current endianness.
2161                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2162     }
2163 #endif
2164 
2165     bool success = false;
2166     if (ConditionPassed(opcode))
2167     {
2168         const uint32_t addr_byte_size = GetAddressByteSize();
2169         const addr_t sp = ReadCoreReg (SP_REG, &success);
2170         if (!success)
2171             return false;
2172         bool single_regs;
2173         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2174         uint32_t imm32; // stack offset
2175         uint32_t regs;  // number of registers
2176         switch (encoding) {
2177         case eEncodingT1:
2178         case eEncodingA1:
2179             single_regs = false;
2180             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2181             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2182             // If UInt(imm8) is odd, see "FLDMX".
2183             regs = Bits32(opcode, 7, 0) / 2;
2184             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2185             if (regs == 0 || regs > 16 || (d + regs) > 32)
2186                 return false;
2187             break;
2188         case eEncodingT2:
2189         case eEncodingA2:
2190             single_regs = true;
2191             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2192             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2193             regs = Bits32(opcode, 7, 0);
2194             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2195             if (regs == 0 || regs > 16 || (d + regs) > 32)
2196                 return false;
2197             break;
2198         default:
2199             return false;
2200         }
2201         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2202         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2203         addr_t sp_offset = imm32;
2204         addr_t addr = sp;
2205         uint32_t i;
2206         uint64_t data; // uint64_t to accommodate 64-bit registers.
2207 
2208         EmulateInstruction::Context context;
2209         context.type = EmulateInstruction::eContextPopRegisterOffStack;
2210 
2211         RegisterInfo dwarf_reg;
2212         RegisterInfo sp_reg;
2213         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2214         for (i=0; i<regs; ++i)
2215         {
2216             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2217             context.SetAddress(addr);
2218             data = MemARead(context, addr, reg_byte_size, 0, &success);
2219             if (!success)
2220                 return false;
2221             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2222                 return false;
2223             addr += reg_byte_size;
2224         }
2225 
2226         context.type = EmulateInstruction::eContextAdjustStackPointer;
2227         context.SetImmediateSigned (sp_offset);
2228 
2229         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2230             return false;
2231     }
2232     return true;
2233 }
2234 
2235 // SVC (previously SWI)
2236 bool
2237 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2238 {
2239 #if 0
2240     // ARM pseudo code...
2241     if (ConditionPassed())
2242     {
2243         EncodingSpecificOperations();
2244         CallSupervisor();
2245     }
2246 #endif
2247 
2248     bool success = false;
2249 
2250     if (ConditionPassed(opcode))
2251     {
2252         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2253         addr_t lr; // next instruction address
2254         if (!success)
2255             return false;
2256         uint32_t imm32; // the immediate constant
2257         uint32_t mode;  // ARM or Thumb mode
2258         switch (encoding) {
2259         case eEncodingT1:
2260             lr = (pc + 2) | 1u; // return address
2261             imm32 = Bits32(opcode, 7, 0);
2262             mode = eModeThumb;
2263             break;
2264         case eEncodingA1:
2265             lr = pc + 4; // return address
2266             imm32 = Bits32(opcode, 23, 0);
2267             mode = eModeARM;
2268             break;
2269         default:
2270             return false;
2271         }
2272 
2273         EmulateInstruction::Context context;
2274         context.type = EmulateInstruction::eContextSupervisorCall;
2275         context.SetISAAndImmediate (mode, imm32);
2276         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2277             return false;
2278     }
2279     return true;
2280 }
2281 
2282 // If Then makes up to four following instructions (the IT block) conditional.
2283 bool
2284 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2285 {
2286 #if 0
2287     // ARM pseudo code...
2288     EncodingSpecificOperations();
2289     ITSTATE.IT<7:0> = firstcond:mask;
2290 #endif
2291 
2292     m_it_session.InitIT(Bits32(opcode, 7, 0));
2293     return true;
2294 }
2295 
2296 bool
2297 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2298 {
2299     // NOP, nothing to do...
2300     return true;
2301 }
2302 
2303 // Branch causes a branch to a target address.
2304 bool
2305 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2306 {
2307 #if 0
2308     // ARM pseudo code...
2309     if (ConditionPassed())
2310     {
2311         EncodingSpecificOperations();
2312         BranchWritePC(PC + imm32);
2313     }
2314 #endif
2315 
2316     bool success = false;
2317 
2318     if (ConditionPassed(opcode))
2319     {
2320         EmulateInstruction::Context context;
2321         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2322         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2323         if (!success)
2324             return false;
2325         addr_t target; // target address
2326         int32_t imm32; // PC-relative offset
2327         switch (encoding) {
2328         case eEncodingT1:
2329             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2330             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2331             target = pc + imm32;
2332             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2333             break;
2334         case eEncodingT2:
2335             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2336             target = pc + imm32;
2337             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2338             break;
2339         case eEncodingT3:
2340             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2341             {
2342             if (Bits32(opcode, 25, 23) == 7)
2343                 return false; // See Branches and miscellaneous control on page A6-235.
2344 
2345             uint32_t S = Bit32(opcode, 26);
2346             uint32_t imm6 = Bits32(opcode, 21, 16);
2347             uint32_t J1 = Bit32(opcode, 13);
2348             uint32_t J2 = Bit32(opcode, 11);
2349             uint32_t imm11 = Bits32(opcode, 10, 0);
2350             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2351             imm32 = llvm::SignExtend32<21>(imm21);
2352             target = pc + imm32;
2353             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2354             break;
2355             }
2356         case eEncodingT4:
2357             {
2358             uint32_t S = Bit32(opcode, 26);
2359             uint32_t imm10 = Bits32(opcode, 25, 16);
2360             uint32_t J1 = Bit32(opcode, 13);
2361             uint32_t J2 = Bit32(opcode, 11);
2362             uint32_t imm11 = Bits32(opcode, 10, 0);
2363             uint32_t I1 = !(J1 ^ S);
2364             uint32_t I2 = !(J2 ^ S);
2365             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2366             imm32 = llvm::SignExtend32<25>(imm25);
2367             target = pc + imm32;
2368             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2369             break;
2370             }
2371         case eEncodingA1:
2372             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2373             target = pc + imm32;
2374             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2375             break;
2376         default:
2377             return false;
2378         }
2379         if (!BranchWritePC(context, target))
2380             return false;
2381     }
2382     return true;
2383 }
2384 
2385 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2386 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2387 // CBNZ, CBZ
2388 bool
2389 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2390 {
2391 #if 0
2392     // ARM pseudo code...
2393     EncodingSpecificOperations();
2394     if nonzero ^ IsZero(R[n]) then
2395         BranchWritePC(PC + imm32);
2396 #endif
2397 
2398     bool success = false;
2399 
2400     // Read the register value from the operand register Rn.
2401     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2402     if (!success)
2403         return false;
2404 
2405     EmulateInstruction::Context context;
2406     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2407     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2408     if (!success)
2409         return false;
2410 
2411     addr_t target;  // target address
2412     uint32_t imm32; // PC-relative offset to branch forward
2413     bool nonzero;
2414     switch (encoding) {
2415     case eEncodingT1:
2416         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2417         nonzero = BitIsSet(opcode, 11);
2418         target = pc + imm32;
2419         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2420         break;
2421     default:
2422         return false;
2423     }
2424     if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2425         if (!BranchWritePC(context, target))
2426             return false;
2427 
2428     return true;
2429 }
2430 
2431 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2432 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2433 // The branch length is twice the value of the byte returned from the table.
2434 //
2435 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2436 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2437 // The branch length is twice the value of the halfword returned from the table.
2438 // TBB, TBH
2439 bool
2440 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2441 {
2442 #if 0
2443     // ARM pseudo code...
2444     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2445     if is_tbh then
2446         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2447     else
2448         halfwords = UInt(MemU[R[n]+R[m], 1]);
2449     BranchWritePC(PC + 2*halfwords);
2450 #endif
2451 
2452     bool success = false;
2453 
2454     if (ConditionPassed(opcode))
2455     {
2456         uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2457         uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2458         bool is_tbh;     // true if table branch halfword
2459         switch (encoding) {
2460         case eEncodingT1:
2461             Rn = Bits32(opcode, 19, 16);
2462             Rm = Bits32(opcode, 3, 0);
2463             is_tbh = BitIsSet(opcode, 4);
2464             if (Rn == 13 || BadReg(Rm))
2465                 return false;
2466             if (InITBlock() && !LastInITBlock())
2467                 return false;
2468             break;
2469         default:
2470             return false;
2471         }
2472 
2473         // Read the address of the table from the operand register Rn.
2474         // The PC can be used, in which case the table immediately follows this instruction.
2475         uint32_t base = ReadCoreReg(Rn, &success);
2476         if (!success)
2477             return false;
2478 
2479         // the table index
2480         uint32_t index = ReadCoreReg(Rm, &success);
2481         if (!success)
2482             return false;
2483 
2484         // the offsetted table address
2485         addr_t addr = base + (is_tbh ? index*2 : index);
2486 
2487         // PC-relative offset to branch forward
2488         EmulateInstruction::Context context;
2489         context.type = EmulateInstruction::eContextTableBranchReadMemory;
2490         uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2491         if (!success)
2492             return false;
2493 
2494         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2495         if (!success)
2496             return false;
2497 
2498         // target address
2499         addr_t target = pc + offset;
2500         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2501         context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2502 
2503         if (!BranchWritePC(context, target))
2504             return false;
2505     }
2506 
2507     return true;
2508 }
2509 
2510 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2511 // It can optionally update the condition flags based on the result.
2512 bool
2513 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2514 {
2515 #if 0
2516     if ConditionPassed() then
2517         EncodingSpecificOperations();
2518         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2519         R[d] = result;
2520         if setflags then
2521             APSR.N = result<31>;
2522             APSR.Z = IsZeroBit(result);
2523             APSR.C = carry;
2524             APSR.V = overflow;
2525 #endif
2526 
2527     bool success = false;
2528 
2529     if (ConditionPassed(opcode))
2530     {
2531         uint32_t d;
2532         uint32_t n;
2533         bool setflags;
2534         uint32_t imm32;
2535         uint32_t carry_out;
2536 
2537         //EncodingSpecificOperations();
2538         switch (encoding)
2539         {
2540             case eEncodingT1:
2541                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2542                 d = Bits32 (opcode, 2, 0);
2543                 n = Bits32 (opcode, 5, 3);
2544                 setflags = !InITBlock();
2545                 imm32 = Bits32 (opcode, 8,6);
2546 
2547                 break;
2548 
2549             case eEncodingT2:
2550                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2551                 d = Bits32 (opcode, 10, 8);
2552                 n = Bits32 (opcode, 10, 8);
2553                 setflags = !InITBlock();
2554                 imm32 = Bits32 (opcode, 7, 0);
2555 
2556                 break;
2557 
2558             case eEncodingT3:
2559                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2560                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2561                 d = Bits32 (opcode, 11, 8);
2562                 n = Bits32 (opcode, 19, 16);
2563                 setflags = BitIsSet (opcode, 20);
2564                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2565 
2566                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2567                 if (n == 13)
2568                     return EmulateADDSPImm(opcode, eEncodingT3);
2569 
2570                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2571                 if (BadReg (d) || (n == 15))
2572                     return false;
2573 
2574                 break;
2575 
2576             case eEncodingT4:
2577             {
2578                 // if Rn == '1111' then SEE ADR;
2579                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2580                 d = Bits32 (opcode, 11, 8);
2581                 n = Bits32 (opcode, 19, 16);
2582                 setflags = false;
2583                 uint32_t i = Bit32 (opcode, 26);
2584                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2585                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2586                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2587 
2588                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2589                 if (n == 13)
2590                     return EmulateADDSPImm(opcode, eEncodingT4);
2591 
2592                 // if BadReg(d) then UNPREDICTABLE;
2593                 if (BadReg (d))
2594                     return false;
2595 
2596                 break;
2597             }
2598 
2599             default:
2600                 return false;
2601         }
2602 
2603         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2604         if (!success)
2605             return false;
2606 
2607         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2608         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2609 
2610         RegisterInfo reg_n;
2611         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2612 
2613         EmulateInstruction::Context context;
2614         context.type = eContextArithmetic;
2615         context.SetRegisterPlusOffset (reg_n, imm32);
2616 
2617         //R[d] = result;
2618         //if setflags then
2619             //APSR.N = result<31>;
2620             //APSR.Z = IsZeroBit(result);
2621             //APSR.C = carry;
2622             //APSR.V = overflow;
2623         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2624             return false;
2625 
2626     }
2627     return true;
2628 }
2629 
2630 // This instruction adds an immediate value to a register value, and writes the result to the destination
2631 // register.  It can optionally update the condition flags based on the result.
2632 bool
2633 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2634 {
2635 #if 0
2636     // ARM pseudo code...
2637     if ConditionPassed() then
2638         EncodingSpecificOperations();
2639         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2640         if d == 15 then
2641             ALUWritePC(result); // setflags is always FALSE here
2642         else
2643             R[d] = result;
2644             if setflags then
2645                 APSR.N = result<31>;
2646                 APSR.Z = IsZeroBit(result);
2647                 APSR.C = carry;
2648                 APSR.V = overflow;
2649 #endif
2650 
2651     bool success = false;
2652 
2653     if (ConditionPassed(opcode))
2654     {
2655         uint32_t Rd, Rn;
2656         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2657         bool setflags;
2658         switch (encoding)
2659         {
2660         case eEncodingA1:
2661             Rd = Bits32(opcode, 15, 12);
2662             Rn = Bits32(opcode, 19, 16);
2663             setflags = BitIsSet(opcode, 20);
2664             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2665             break;
2666         default:
2667             return false;
2668         }
2669 
2670         // Read the first operand.
2671         uint32_t val1 = ReadCoreReg(Rn, &success);
2672         if (!success)
2673             return false;
2674 
2675         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2676 
2677         EmulateInstruction::Context context;
2678         if (Rd == 13)
2679             context.type = EmulateInstruction::eContextAdjustStackPointer;
2680         else if (Rd == GetFramePointerRegisterNumber())
2681             context.type = EmulateInstruction::eContextSetFramePointer;
2682         else
2683             context.type = EmulateInstruction::eContextRegisterPlusOffset;
2684 
2685         RegisterInfo dwarf_reg;
2686         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2687         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2688 
2689         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2690             return false;
2691     }
2692     return true;
2693 }
2694 
2695 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2696 // to the destination register. It can optionally update the condition flags based on the result.
2697 bool
2698 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2699 {
2700 #if 0
2701     // ARM pseudo code...
2702     if ConditionPassed() then
2703         EncodingSpecificOperations();
2704         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2705         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2706         if d == 15 then
2707             ALUWritePC(result); // setflags is always FALSE here
2708         else
2709             R[d] = result;
2710             if setflags then
2711                 APSR.N = result<31>;
2712                 APSR.Z = IsZeroBit(result);
2713                 APSR.C = carry;
2714                 APSR.V = overflow;
2715 #endif
2716 
2717     bool success = false;
2718 
2719     if (ConditionPassed(opcode))
2720     {
2721         uint32_t Rd, Rn, Rm;
2722         ARM_ShifterType shift_t;
2723         uint32_t shift_n; // the shift applied to the value read from Rm
2724         bool setflags;
2725         switch (encoding)
2726         {
2727         case eEncodingT1:
2728             Rd = Bits32(opcode, 2, 0);
2729             Rn = Bits32(opcode, 5, 3);
2730             Rm = Bits32(opcode, 8, 6);
2731             setflags = !InITBlock();
2732             shift_t = SRType_LSL;
2733             shift_n = 0;
2734             break;
2735         case eEncodingT2:
2736             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2737             Rm = Bits32(opcode, 6, 3);
2738             setflags = false;
2739             shift_t = SRType_LSL;
2740             shift_n = 0;
2741             if (Rn == 15 && Rm == 15)
2742                 return false;
2743             if (Rd == 15 && InITBlock() && !LastInITBlock())
2744                 return false;
2745             break;
2746         case eEncodingA1:
2747             Rd = Bits32(opcode, 15, 12);
2748             Rn = Bits32(opcode, 19, 16);
2749             Rm = Bits32(opcode, 3, 0);
2750             setflags = BitIsSet(opcode, 20);
2751             shift_n = DecodeImmShiftARM(opcode, shift_t);
2752             break;
2753         default:
2754             return false;
2755         }
2756 
2757         // Read the first operand.
2758         uint32_t val1 = ReadCoreReg(Rn, &success);
2759         if (!success)
2760             return false;
2761 
2762         // Read the second operand.
2763         uint32_t val2 = ReadCoreReg(Rm, &success);
2764         if (!success)
2765             return false;
2766 
2767         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2768         if (!success)
2769             return false;
2770         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2771 
2772         EmulateInstruction::Context context;
2773         context.type = eContextArithmetic;
2774         RegisterInfo op1_reg;
2775         RegisterInfo op2_reg;
2776         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2777         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2778         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2779 
2780         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2781             return false;
2782     }
2783     return true;
2784 }
2785 
2786 // Compare Negative (immediate) adds a register value and an immediate value.
2787 // It updates the condition flags based on the result, and discards the result.
2788 bool
2789 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2790 {
2791 #if 0
2792     // ARM pseudo code...
2793     if ConditionPassed() then
2794         EncodingSpecificOperations();
2795         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2796         APSR.N = result<31>;
2797         APSR.Z = IsZeroBit(result);
2798         APSR.C = carry;
2799         APSR.V = overflow;
2800 #endif
2801 
2802     bool success = false;
2803 
2804     uint32_t Rn; // the first operand
2805     uint32_t imm32; // the immediate value to be compared with
2806     switch (encoding) {
2807     case eEncodingT1:
2808         Rn = Bits32(opcode, 19, 16);
2809         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2810         if (Rn == 15)
2811             return false;
2812         break;
2813     case eEncodingA1:
2814         Rn = Bits32(opcode, 19, 16);
2815         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2816         break;
2817     default:
2818         return false;
2819     }
2820     // Read the register value from the operand register Rn.
2821     uint32_t reg_val = ReadCoreReg(Rn, &success);
2822     if (!success)
2823         return false;
2824 
2825     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2826 
2827     EmulateInstruction::Context context;
2828     context.type = EmulateInstruction::eContextImmediate;
2829     context.SetNoArgs ();
2830     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2831         return false;
2832 
2833     return true;
2834 }
2835 
2836 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2837 // It updates the condition flags based on the result, and discards the result.
2838 bool
2839 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2840 {
2841 #if 0
2842     // ARM pseudo code...
2843     if ConditionPassed() then
2844         EncodingSpecificOperations();
2845         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2846         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2847         APSR.N = result<31>;
2848         APSR.Z = IsZeroBit(result);
2849         APSR.C = carry;
2850         APSR.V = overflow;
2851 #endif
2852 
2853     bool success = false;
2854 
2855     uint32_t Rn; // the first operand
2856     uint32_t Rm; // the second operand
2857     ARM_ShifterType shift_t;
2858     uint32_t shift_n; // the shift applied to the value read from Rm
2859     switch (encoding) {
2860     case eEncodingT1:
2861         Rn = Bits32(opcode, 2, 0);
2862         Rm = Bits32(opcode, 5, 3);
2863         shift_t = SRType_LSL;
2864         shift_n = 0;
2865         break;
2866     case eEncodingT2:
2867         Rn = Bits32(opcode, 19, 16);
2868         Rm = Bits32(opcode, 3, 0);
2869         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2870         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2871         if (Rn == 15 || BadReg(Rm))
2872             return false;
2873         break;
2874     case eEncodingA1:
2875         Rn = Bits32(opcode, 19, 16);
2876         Rm = Bits32(opcode, 3, 0);
2877         shift_n = DecodeImmShiftARM(opcode, shift_t);
2878         break;
2879     default:
2880         return false;
2881     }
2882     // Read the register value from register Rn.
2883     uint32_t val1 = ReadCoreReg(Rn, &success);
2884     if (!success)
2885         return false;
2886 
2887     // Read the register value from register Rm.
2888     uint32_t val2 = ReadCoreReg(Rm, &success);
2889     if (!success)
2890         return false;
2891 
2892     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2893     if (!success)
2894         return false;
2895     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2896 
2897     EmulateInstruction::Context context;
2898     context.type = EmulateInstruction::eContextImmediate;
2899     context.SetNoArgs();
2900     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2901         return false;
2902 
2903     return true;
2904 }
2905 
2906 // Compare (immediate) subtracts an immediate value from a register value.
2907 // It updates the condition flags based on the result, and discards the result.
2908 bool
2909 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2910 {
2911 #if 0
2912     // ARM pseudo code...
2913     if ConditionPassed() then
2914         EncodingSpecificOperations();
2915         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2916         APSR.N = result<31>;
2917         APSR.Z = IsZeroBit(result);
2918         APSR.C = carry;
2919         APSR.V = overflow;
2920 #endif
2921 
2922     bool success = false;
2923 
2924     uint32_t Rn; // the first operand
2925     uint32_t imm32; // the immediate value to be compared with
2926     switch (encoding) {
2927     case eEncodingT1:
2928         Rn = Bits32(opcode, 10, 8);
2929         imm32 = Bits32(opcode, 7, 0);
2930         break;
2931     case eEncodingT2:
2932         Rn = Bits32(opcode, 19, 16);
2933         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2934         if (Rn == 15)
2935             return false;
2936         break;
2937     case eEncodingA1:
2938         Rn = Bits32(opcode, 19, 16);
2939         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2940         break;
2941     default:
2942         return false;
2943     }
2944     // Read the register value from the operand register Rn.
2945     uint32_t reg_val = ReadCoreReg(Rn, &success);
2946     if (!success)
2947         return false;
2948 
2949     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2950 
2951     EmulateInstruction::Context context;
2952     context.type = EmulateInstruction::eContextImmediate;
2953     context.SetNoArgs ();
2954     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2955         return false;
2956 
2957     return true;
2958 }
2959 
2960 // Compare (register) subtracts an optionally-shifted register value from a register value.
2961 // It updates the condition flags based on the result, and discards the result.
2962 bool
2963 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2964 {
2965 #if 0
2966     // ARM pseudo code...
2967     if ConditionPassed() then
2968         EncodingSpecificOperations();
2969         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2970         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2971         APSR.N = result<31>;
2972         APSR.Z = IsZeroBit(result);
2973         APSR.C = carry;
2974         APSR.V = overflow;
2975 #endif
2976 
2977     bool success = false;
2978 
2979     uint32_t Rn; // the first operand
2980     uint32_t Rm; // the second operand
2981     ARM_ShifterType shift_t;
2982     uint32_t shift_n; // the shift applied to the value read from Rm
2983     switch (encoding) {
2984     case eEncodingT1:
2985         Rn = Bits32(opcode, 2, 0);
2986         Rm = Bits32(opcode, 5, 3);
2987         shift_t = SRType_LSL;
2988         shift_n = 0;
2989         break;
2990     case eEncodingT2:
2991         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2992         Rm = Bits32(opcode, 6, 3);
2993         shift_t = SRType_LSL;
2994         shift_n = 0;
2995         if (Rn < 8 && Rm < 8)
2996             return false;
2997         if (Rn == 15 || Rm == 15)
2998             return false;
2999         break;
3000     case eEncodingT3:
3001         Rn = Bits32(opcode, 19, 16);
3002         Rm = Bits32(opcode, 3, 0);
3003         shift_n = DecodeImmShiftThumb(opcode, shift_t);
3004         if (Rn == 15 || BadReg(Rm))
3005             return false;
3006         break;
3007     case eEncodingA1:
3008         Rn = Bits32(opcode, 19, 16);
3009         Rm = Bits32(opcode, 3, 0);
3010         shift_n = DecodeImmShiftARM(opcode, shift_t);
3011         break;
3012     default:
3013         return false;
3014     }
3015     // Read the register value from register Rn.
3016     uint32_t val1 = ReadCoreReg(Rn, &success);
3017     if (!success)
3018         return false;
3019 
3020     // Read the register value from register Rm.
3021     uint32_t val2 = ReadCoreReg(Rm, &success);
3022     if (!success)
3023         return false;
3024 
3025     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3026     if (!success)
3027         return false;
3028     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3029 
3030     EmulateInstruction::Context context;
3031     context.type = EmulateInstruction::eContextImmediate;
3032     context.SetNoArgs();
3033     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3034         return false;
3035 
3036     return true;
3037 }
3038 
3039 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
3040 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
3041 // optionally update the condition flags based on the result.
3042 bool
3043 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
3044 {
3045 #if 0
3046     // ARM pseudo code...
3047     if ConditionPassed() then
3048         EncodingSpecificOperations();
3049         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3050         if d == 15 then         // Can only occur for ARM encoding
3051             ALUWritePC(result); // setflags is always FALSE here
3052         else
3053             R[d] = result;
3054             if setflags then
3055                 APSR.N = result<31>;
3056                 APSR.Z = IsZeroBit(result);
3057                 APSR.C = carry;
3058                 // APSR.V unchanged
3059 #endif
3060 
3061     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3062 }
3063 
3064 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3065 // shifting in copies of its sign bit, and writes the result to the destination register.
3066 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3067 // the condition flags based on the result.
3068 bool
3069 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3070 {
3071 #if 0
3072     // ARM pseudo code...
3073     if ConditionPassed() then
3074         EncodingSpecificOperations();
3075         shift_n = UInt(R[m]<7:0>);
3076         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3077         R[d] = result;
3078         if setflags then
3079             APSR.N = result<31>;
3080             APSR.Z = IsZeroBit(result);
3081             APSR.C = carry;
3082             // APSR.V unchanged
3083 #endif
3084 
3085     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3086 }
3087 
3088 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3089 // shifting in zeros, and writes the result to the destination register.  It can optionally
3090 // update the condition flags based on the result.
3091 bool
3092 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3093 {
3094 #if 0
3095     // ARM pseudo code...
3096     if ConditionPassed() then
3097         EncodingSpecificOperations();
3098         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3099         if d == 15 then         // Can only occur for ARM encoding
3100             ALUWritePC(result); // setflags is always FALSE here
3101         else
3102             R[d] = result;
3103             if setflags then
3104                 APSR.N = result<31>;
3105                 APSR.Z = IsZeroBit(result);
3106                 APSR.C = carry;
3107                 // APSR.V unchanged
3108 #endif
3109 
3110     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3111 }
3112 
3113 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3114 // shifting in zeros, and writes the result to the destination register.  The variable number
3115 // of bits is read from the bottom byte of a register. It can optionally update the condition
3116 // flags based on the result.
3117 bool
3118 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3119 {
3120 #if 0
3121     // ARM pseudo code...
3122     if ConditionPassed() then
3123         EncodingSpecificOperations();
3124         shift_n = UInt(R[m]<7:0>);
3125         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3126         R[d] = result;
3127         if setflags then
3128             APSR.N = result<31>;
3129             APSR.Z = IsZeroBit(result);
3130             APSR.C = carry;
3131             // APSR.V unchanged
3132 #endif
3133 
3134     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3135 }
3136 
3137 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3138 // shifting in zeros, and writes the result to the destination register.  It can optionally
3139 // update the condition flags based on the result.
3140 bool
3141 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3142 {
3143 #if 0
3144     // ARM pseudo code...
3145     if ConditionPassed() then
3146         EncodingSpecificOperations();
3147         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3148         if d == 15 then         // Can only occur for ARM encoding
3149             ALUWritePC(result); // setflags is always FALSE here
3150         else
3151             R[d] = result;
3152             if setflags then
3153                 APSR.N = result<31>;
3154                 APSR.Z = IsZeroBit(result);
3155                 APSR.C = carry;
3156                 // APSR.V unchanged
3157 #endif
3158 
3159     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3160 }
3161 
3162 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3163 // shifting in zeros, and writes the result to the destination register.  The variable number
3164 // of bits is read from the bottom byte of a register. It can optionally update the condition
3165 // flags based on the result.
3166 bool
3167 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3168 {
3169 #if 0
3170     // ARM pseudo code...
3171     if ConditionPassed() then
3172         EncodingSpecificOperations();
3173         shift_n = UInt(R[m]<7:0>);
3174         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3175         R[d] = result;
3176         if setflags then
3177             APSR.N = result<31>;
3178             APSR.Z = IsZeroBit(result);
3179             APSR.C = carry;
3180             // APSR.V unchanged
3181 #endif
3182 
3183     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3184 }
3185 
3186 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3187 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3188 // It can optionally update the condition flags based on the result.
3189 bool
3190 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3191 {
3192 #if 0
3193     // ARM pseudo code...
3194     if ConditionPassed() then
3195         EncodingSpecificOperations();
3196         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3197         if d == 15 then         // Can only occur for ARM encoding
3198             ALUWritePC(result); // setflags is always FALSE here
3199         else
3200             R[d] = result;
3201             if setflags then
3202                 APSR.N = result<31>;
3203                 APSR.Z = IsZeroBit(result);
3204                 APSR.C = carry;
3205                 // APSR.V unchanged
3206 #endif
3207 
3208     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3209 }
3210 
3211 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3212 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3213 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3214 // flags based on the result.
3215 bool
3216 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3217 {
3218 #if 0
3219     // ARM pseudo code...
3220     if ConditionPassed() then
3221         EncodingSpecificOperations();
3222         shift_n = UInt(R[m]<7:0>);
3223         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3224         R[d] = result;
3225         if setflags then
3226             APSR.N = result<31>;
3227             APSR.Z = IsZeroBit(result);
3228             APSR.C = carry;
3229             // APSR.V unchanged
3230 #endif
3231 
3232     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3233 }
3234 
3235 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3236 // with the carry flag shifted into bit [31].
3237 //
3238 // RRX can optionally update the condition flags based on the result.
3239 // In that case, bit [0] is shifted into the carry flag.
3240 bool
3241 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3242 {
3243 #if 0
3244     // ARM pseudo code...
3245     if ConditionPassed() then
3246         EncodingSpecificOperations();
3247         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3248         if d == 15 then         // Can only occur for ARM encoding
3249             ALUWritePC(result); // setflags is always FALSE here
3250         else
3251             R[d] = result;
3252             if setflags then
3253                 APSR.N = result<31>;
3254                 APSR.Z = IsZeroBit(result);
3255                 APSR.C = carry;
3256                 // APSR.V unchanged
3257 #endif
3258 
3259     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3260 }
3261 
3262 bool
3263 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3264 {
3265 //    assert(shift_type == SRType_ASR
3266 //           || shift_type == SRType_LSL
3267 //           || shift_type == SRType_LSR
3268 //           || shift_type == SRType_ROR
3269 //           || shift_type == SRType_RRX);
3270 
3271     bool success = false;
3272 
3273     if (ConditionPassed(opcode))
3274     {
3275         uint32_t Rd;    // the destination register
3276         uint32_t Rm;    // the first operand register
3277         uint32_t imm5;  // encoding for the shift amount
3278         uint32_t carry; // the carry bit after the shift operation
3279         bool setflags;
3280 
3281         // Special case handling!
3282         // A8.6.139 ROR (immediate) -- Encoding T1
3283         ARMEncoding use_encoding = encoding;
3284         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3285         {
3286             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3287             // have the same decoding of bit fields as the other Thumb2 shift operations.
3288             use_encoding = eEncodingT2;
3289         }
3290 
3291         switch (use_encoding) {
3292         case eEncodingT1:
3293             // Due to the above special case handling!
3294             if (shift_type == SRType_ROR)
3295                 return false;
3296 
3297             Rd = Bits32(opcode, 2, 0);
3298             Rm = Bits32(opcode, 5, 3);
3299             setflags = !InITBlock();
3300             imm5 = Bits32(opcode, 10, 6);
3301             break;
3302         case eEncodingT2:
3303             // A8.6.141 RRX
3304             // There's no imm form of RRX instructions.
3305             if (shift_type == SRType_RRX)
3306                 return false;
3307 
3308             Rd = Bits32(opcode, 11, 8);
3309             Rm = Bits32(opcode, 3, 0);
3310             setflags = BitIsSet(opcode, 20);
3311             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3312             if (BadReg(Rd) || BadReg(Rm))
3313                 return false;
3314             break;
3315         case eEncodingA1:
3316             Rd = Bits32(opcode, 15, 12);
3317             Rm = Bits32(opcode, 3, 0);
3318             setflags = BitIsSet(opcode, 20);
3319             imm5 = Bits32(opcode, 11, 7);
3320             break;
3321         default:
3322             return false;
3323         }
3324 
3325         // A8.6.139 ROR (immediate)
3326         if (shift_type == SRType_ROR && imm5 == 0)
3327             shift_type = SRType_RRX;
3328 
3329         // Get the first operand.
3330         uint32_t value = ReadCoreReg (Rm, &success);
3331         if (!success)
3332             return false;
3333 
3334         // Decode the shift amount if not RRX.
3335         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3336 
3337         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3338         if (!success)
3339             return false;
3340 
3341         // The context specifies that an immediate is to be moved into Rd.
3342         EmulateInstruction::Context context;
3343         context.type = EmulateInstruction::eContextImmediate;
3344         context.SetNoArgs ();
3345 
3346         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3347             return false;
3348     }
3349     return true;
3350 }
3351 
3352 bool
3353 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3354 {
3355     // assert(shift_type == SRType_ASR
3356     //        || shift_type == SRType_LSL
3357     //        || shift_type == SRType_LSR
3358     //        || shift_type == SRType_ROR);
3359 
3360     bool success = false;
3361 
3362     if (ConditionPassed(opcode))
3363     {
3364         uint32_t Rd;    // the destination register
3365         uint32_t Rn;    // the first operand register
3366         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3367         uint32_t carry; // the carry bit after the shift operation
3368         bool setflags;
3369         switch (encoding) {
3370         case eEncodingT1:
3371             Rd = Bits32(opcode, 2, 0);
3372             Rn = Rd;
3373             Rm = Bits32(opcode, 5, 3);
3374             setflags = !InITBlock();
3375             break;
3376         case eEncodingT2:
3377             Rd = Bits32(opcode, 11, 8);
3378             Rn = Bits32(opcode, 19, 16);
3379             Rm = Bits32(opcode, 3, 0);
3380             setflags = BitIsSet(opcode, 20);
3381             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3382                 return false;
3383             break;
3384         case eEncodingA1:
3385             Rd = Bits32(opcode, 15, 12);
3386             Rn = Bits32(opcode, 3, 0);
3387             Rm = Bits32(opcode, 11, 8);
3388             setflags = BitIsSet(opcode, 20);
3389             if (Rd == 15 || Rn == 15 || Rm == 15)
3390                 return false;
3391             break;
3392         default:
3393             return false;
3394         }
3395 
3396         // Get the first operand.
3397         uint32_t value = ReadCoreReg (Rn, &success);
3398         if (!success)
3399             return false;
3400         // Get the Rm register content.
3401         uint32_t val = ReadCoreReg (Rm, &success);
3402         if (!success)
3403             return false;
3404 
3405         // Get the shift amount.
3406         uint32_t amt = Bits32(val, 7, 0);
3407 
3408         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3409         if (!success)
3410             return false;
3411 
3412         // The context specifies that an immediate is to be moved into Rd.
3413         EmulateInstruction::Context context;
3414         context.type = EmulateInstruction::eContextImmediate;
3415         context.SetNoArgs ();
3416 
3417         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3418             return false;
3419     }
3420     return true;
3421 }
3422 
3423 // LDM loads multiple registers from consecutive memory locations, using an
3424 // address from a base register.  Optionally the address just above the highest of those locations
3425 // can be written back to the base register.
3426 bool
3427 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3428 {
3429 #if 0
3430     // ARM pseudo code...
3431     if ConditionPassed()
3432         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3433         address = R[n];
3434 
3435         for i = 0 to 14
3436             if registers<i> == '1' then
3437                 R[i] = MemA[address, 4]; address = address + 4;
3438         if registers<15> == '1' then
3439             LoadWritePC (MemA[address, 4]);
3440 
3441         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3442         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3443 
3444 #endif
3445 
3446     bool success = false;
3447     if (ConditionPassed(opcode))
3448     {
3449         uint32_t n;
3450         uint32_t registers = 0;
3451         bool wback;
3452         const uint32_t addr_byte_size = GetAddressByteSize();
3453         switch (encoding)
3454         {
3455             case eEncodingT1:
3456                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3457                 n = Bits32 (opcode, 10, 8);
3458                 registers = Bits32 (opcode, 7, 0);
3459                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3460                 wback = BitIsClear (registers, n);
3461                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3462                 if (BitCount(registers) < 1)
3463                     return false;
3464                 break;
3465             case eEncodingT2:
3466                 // if W == '1' && Rn == '1101' then SEE POP;
3467                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3468                 n = Bits32 (opcode, 19, 16);
3469                 registers = Bits32 (opcode, 15, 0);
3470                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3471                 wback = BitIsSet (opcode, 21);
3472 
3473                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3474                 if ((n == 15)
3475                     || (BitCount (registers) < 2)
3476                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3477                     return false;
3478 
3479                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3480                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3481                     return false;
3482 
3483                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3484                 if (wback
3485                     && BitIsSet (registers, n))
3486                     return false;
3487                 break;
3488 
3489             case eEncodingA1:
3490                 n = Bits32 (opcode, 19, 16);
3491                 registers = Bits32 (opcode, 15, 0);
3492                 wback = BitIsSet (opcode, 21);
3493                 if ((n == 15)
3494                     || (BitCount (registers) < 1))
3495                     return false;
3496                 break;
3497             default:
3498                 return false;
3499         }
3500 
3501         int32_t offset = 0;
3502         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3503         if (!success)
3504             return false;
3505 
3506         EmulateInstruction::Context context;
3507         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3508         RegisterInfo dwarf_reg;
3509         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3510         context.SetRegisterPlusOffset (dwarf_reg, offset);
3511 
3512         for (int i = 0; i < 14; ++i)
3513         {
3514             if (BitIsSet (registers, i))
3515             {
3516                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3517                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3518                 if (wback && (n == 13)) // Pop Instruction
3519                 {
3520                     context.type = EmulateInstruction::eContextPopRegisterOffStack;
3521                     context.SetAddress(base_address + offset);
3522                 }
3523 
3524                 // R[i] = MemA [address, 4]; address = address + 4;
3525                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3526                 if (!success)
3527                     return false;
3528 
3529                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3530                     return false;
3531 
3532                 offset += addr_byte_size;
3533             }
3534         }
3535 
3536         if (BitIsSet (registers, 15))
3537         {
3538             //LoadWritePC (MemA [address, 4]);
3539             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3540             context.SetRegisterPlusOffset (dwarf_reg, offset);
3541             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3542             if (!success)
3543                 return false;
3544             // In ARMv5T and above, this is an interworking branch.
3545             if (!LoadWritePC(context, data))
3546                 return false;
3547         }
3548 
3549         if (wback && BitIsClear (registers, n))
3550         {
3551             // R[n] = R[n] + 4 * BitCount (registers)
3552             int32_t offset = addr_byte_size * BitCount (registers);
3553             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3554             context.SetRegisterPlusOffset (dwarf_reg, offset);
3555 
3556             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3557                 return false;
3558         }
3559         if (wback && BitIsSet (registers, n))
3560             // R[n] bits(32) UNKNOWN;
3561             return WriteBits32Unknown (n);
3562     }
3563     return true;
3564 }
3565 
3566 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3567 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3568 // can optionally be written back to the base register.
3569 bool
3570 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3571 {
3572 #if 0
3573     // ARM pseudo code...
3574     if ConditionPassed() then
3575         EncodingSpecificOperations();
3576         address = R[n] - 4*BitCount(registers) + 4;
3577 
3578         for i = 0 to 14
3579             if registers<i> == '1' then
3580                   R[i] = MemA[address,4]; address = address + 4;
3581 
3582         if registers<15> == '1' then
3583             LoadWritePC(MemA[address,4]);
3584 
3585         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3586         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3587 #endif
3588 
3589     bool success = false;
3590 
3591     if (ConditionPassed(opcode))
3592     {
3593         uint32_t n;
3594         uint32_t registers = 0;
3595         bool wback;
3596         const uint32_t addr_byte_size = GetAddressByteSize();
3597 
3598         // EncodingSpecificOperations();
3599         switch (encoding)
3600         {
3601             case eEncodingA1:
3602                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3603                 n = Bits32 (opcode, 19, 16);
3604                 registers = Bits32 (opcode, 15, 0);
3605                 wback = BitIsSet (opcode, 21);
3606 
3607                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3608                 if ((n == 15) || (BitCount (registers) < 1))
3609                     return false;
3610 
3611                 break;
3612 
3613             default:
3614                 return false;
3615         }
3616         // address = R[n] - 4*BitCount(registers) + 4;
3617 
3618         int32_t offset = 0;
3619         addr_t Rn = ReadCoreReg (n, &success);
3620 
3621         if (!success)
3622             return false;
3623 
3624         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3625 
3626         EmulateInstruction::Context context;
3627         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3628         RegisterInfo dwarf_reg;
3629         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3630         context.SetRegisterPlusOffset (dwarf_reg, offset);
3631 
3632         // for i = 0 to 14
3633         for (int i = 0; i < 14; ++i)
3634         {
3635             // if registers<i> == '1' then
3636             if (BitIsSet (registers, i))
3637             {
3638                   // R[i] = MemA[address,4]; address = address + 4;
3639                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3640                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3641                   if (!success)
3642                       return false;
3643                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3644                       return false;
3645                   offset += addr_byte_size;
3646             }
3647         }
3648 
3649         // if registers<15> == '1' then
3650         //     LoadWritePC(MemA[address,4]);
3651         if (BitIsSet (registers, 15))
3652         {
3653             context.SetRegisterPlusOffset (dwarf_reg, offset);
3654             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3655             if (!success)
3656                 return false;
3657             // In ARMv5T and above, this is an interworking branch.
3658             if (!LoadWritePC(context, data))
3659                 return false;
3660         }
3661 
3662         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3663         if (wback && BitIsClear (registers, n))
3664         {
3665             if (!success)
3666                 return false;
3667 
3668             offset = (addr_byte_size * BitCount (registers)) * -1;
3669             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3670             context.SetImmediateSigned (offset);
3671             addr_t addr = Rn + offset;
3672             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3673                 return false;
3674         }
3675 
3676         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3677         if (wback && BitIsSet (registers, n))
3678             return WriteBits32Unknown (n);
3679     }
3680     return true;
3681 }
3682 
3683 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3684 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3685 // be optionally written back to the base register.
3686 bool
3687 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3688 {
3689 #if 0
3690     // ARM pseudo code...
3691     if ConditionPassed() then
3692         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3693         address = R[n] - 4*BitCount(registers);
3694 
3695         for i = 0 to 14
3696             if registers<i> == '1' then
3697                   R[i] = MemA[address,4]; address = address + 4;
3698         if registers<15> == '1' then
3699                   LoadWritePC(MemA[address,4]);
3700 
3701         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3702         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3703 #endif
3704 
3705     bool success = false;
3706 
3707     if (ConditionPassed(opcode))
3708     {
3709         uint32_t n;
3710         uint32_t registers = 0;
3711         bool wback;
3712         const uint32_t addr_byte_size = GetAddressByteSize();
3713         switch (encoding)
3714         {
3715             case eEncodingT1:
3716                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3717                 n = Bits32 (opcode, 19, 16);
3718                 registers = Bits32 (opcode, 15, 0);
3719                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3720                 wback = BitIsSet (opcode, 21);
3721 
3722                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3723                 if ((n == 15)
3724                     || (BitCount (registers) < 2)
3725                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3726                     return false;
3727 
3728                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3729                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3730                     return false;
3731 
3732                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3733                 if (wback && BitIsSet (registers, n))
3734                     return false;
3735 
3736                 break;
3737 
3738             case eEncodingA1:
3739                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3740                 n = Bits32 (opcode, 19, 16);
3741                 registers = Bits32 (opcode, 15, 0);
3742                 wback = BitIsSet (opcode, 21);
3743 
3744                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3745                 if ((n == 15) || (BitCount (registers) < 1))
3746                     return false;
3747 
3748                 break;
3749 
3750             default:
3751                 return false;
3752         }
3753 
3754         // address = R[n] - 4*BitCount(registers);
3755 
3756         int32_t offset = 0;
3757         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3758 
3759         if (!success)
3760             return false;
3761 
3762         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3763         EmulateInstruction::Context context;
3764         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3765         RegisterInfo dwarf_reg;
3766         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3767         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3768 
3769         for (int i = 0; i < 14; ++i)
3770         {
3771             if (BitIsSet (registers, i))
3772             {
3773                 // R[i] = MemA[address,4]; address = address + 4;
3774                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3775                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3776                 if (!success)
3777                     return false;
3778 
3779                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3780                     return false;
3781 
3782                 offset += addr_byte_size;
3783             }
3784         }
3785 
3786         // if registers<15> == '1' then
3787         //     LoadWritePC(MemA[address,4]);
3788         if (BitIsSet (registers, 15))
3789         {
3790             context.SetRegisterPlusOffset (dwarf_reg, offset);
3791             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3792             if (!success)
3793                 return false;
3794             // In ARMv5T and above, this is an interworking branch.
3795             if (!LoadWritePC(context, data))
3796                 return false;
3797         }
3798 
3799         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3800         if (wback && BitIsClear (registers, n))
3801         {
3802             if (!success)
3803                 return false;
3804 
3805             offset = (addr_byte_size * BitCount (registers)) * -1;
3806             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3807             context.SetImmediateSigned (offset);
3808             addr_t addr = Rn + offset;
3809             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3810                 return false;
3811         }
3812 
3813         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3814         if (wback && BitIsSet (registers, n))
3815             return WriteBits32Unknown (n);
3816     }
3817     return true;
3818 }
3819 
3820 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3821 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3822 // optinoally be written back to the base register.
3823 bool
3824 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3825 {
3826 #if 0
3827     if ConditionPassed() then
3828         EncodingSpecificOperations();
3829         address = R[n] + 4;
3830 
3831         for i = 0 to 14
3832             if registers<i> == '1' then
3833                   R[i] = MemA[address,4]; address = address + 4;
3834         if registers<15> == '1' then
3835             LoadWritePC(MemA[address,4]);
3836 
3837         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3838         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3839 #endif
3840 
3841     bool success = false;
3842 
3843     if (ConditionPassed(opcode))
3844     {
3845         uint32_t n;
3846         uint32_t registers = 0;
3847         bool wback;
3848         const uint32_t addr_byte_size = GetAddressByteSize();
3849         switch (encoding)
3850         {
3851             case eEncodingA1:
3852                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3853                 n = Bits32 (opcode, 19, 16);
3854                 registers = Bits32 (opcode, 15, 0);
3855                 wback = BitIsSet (opcode, 21);
3856 
3857                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3858                 if ((n == 15) || (BitCount (registers) < 1))
3859                     return false;
3860 
3861                 break;
3862             default:
3863                 return false;
3864         }
3865         // address = R[n] + 4;
3866 
3867         int32_t offset = 0;
3868         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3869 
3870         if (!success)
3871             return false;
3872 
3873         addr_t address = Rn + addr_byte_size;
3874 
3875         EmulateInstruction::Context context;
3876         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3877         RegisterInfo dwarf_reg;
3878         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3879         context.SetRegisterPlusOffset (dwarf_reg, offset);
3880 
3881         for (int i = 0; i < 14; ++i)
3882         {
3883             if (BitIsSet (registers, i))
3884             {
3885                 // R[i] = MemA[address,4]; address = address + 4;
3886 
3887                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3888                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3889                 if (!success)
3890                     return false;
3891 
3892                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3893                     return false;
3894 
3895                 offset += addr_byte_size;
3896             }
3897         }
3898 
3899         // if registers<15> == '1' then
3900         //     LoadWritePC(MemA[address,4]);
3901         if (BitIsSet (registers, 15))
3902         {
3903             context.SetRegisterPlusOffset (dwarf_reg, offset);
3904             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3905             if (!success)
3906                 return false;
3907             // In ARMv5T and above, this is an interworking branch.
3908             if (!LoadWritePC(context, data))
3909                 return false;
3910         }
3911 
3912         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3913         if (wback && BitIsClear (registers, n))
3914         {
3915             if (!success)
3916                 return false;
3917 
3918             offset = addr_byte_size * BitCount (registers);
3919             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3920             context.SetImmediateSigned (offset);
3921             addr_t addr = Rn + offset;
3922             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3923                 return false;
3924         }
3925 
3926         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3927         if (wback && BitIsSet (registers, n))
3928             return WriteBits32Unknown (n);
3929     }
3930     return true;
3931 }
3932 
3933 // Load Register (immediate) calculates an address from a base register value and
3934 // an immediate offset, loads a word from memory, and writes to a register.
3935 // LDR (immediate, Thumb)
3936 bool
3937 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3938 {
3939 #if 0
3940     // ARM pseudo code...
3941     if (ConditionPassed())
3942     {
3943         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3944         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3945         address = if index then offset_addr else R[n];
3946         data = MemU[address,4];
3947         if wback then R[n] = offset_addr;
3948         if t == 15 then
3949             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3950         elsif UnalignedSupport() || address<1:0> = '00' then
3951             R[t] = data;
3952         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3953     }
3954 #endif
3955 
3956     bool success = false;
3957 
3958     if (ConditionPassed(opcode))
3959     {
3960         uint32_t Rt; // the destination register
3961         uint32_t Rn; // the base register
3962         uint32_t imm32; // the immediate offset used to form the address
3963         addr_t offset_addr; // the offset address
3964         addr_t address; // the calculated address
3965         uint32_t data; // the literal data value from memory load
3966         bool add, index, wback;
3967         switch (encoding) {
3968             case eEncodingT1:
3969                 Rt = Bits32(opcode, 2, 0);
3970                 Rn = Bits32(opcode, 5, 3);
3971                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3972                 // index = TRUE; add = TRUE; wback = FALSE
3973                 add = true;
3974                 index = true;
3975                 wback = false;
3976 
3977                 break;
3978 
3979             case eEncodingT2:
3980                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3981                 Rt = Bits32 (opcode, 10, 8);
3982                 Rn = 13;
3983                 imm32 = Bits32 (opcode, 7, 0) << 2;
3984 
3985                 // index = TRUE; add = TRUE; wback = FALSE;
3986                 index = true;
3987                 add = true;
3988                 wback = false;
3989 
3990                 break;
3991 
3992             case eEncodingT3:
3993                 // if Rn == '1111' then SEE LDR (literal);
3994                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3995                 Rt = Bits32 (opcode, 15, 12);
3996                 Rn = Bits32 (opcode, 19, 16);
3997                 imm32 = Bits32 (opcode, 11, 0);
3998 
3999                 // index = TRUE; add = TRUE; wback = FALSE;
4000                 index = true;
4001                 add = true;
4002                 wback = false;
4003 
4004                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4005                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4006                     return false;
4007 
4008                 break;
4009 
4010             case eEncodingT4:
4011                 // if Rn == '1111' then SEE LDR (literal);
4012                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4013                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
4014                 // if P == '0' && W == '0' then UNDEFINED;
4015                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
4016                     return false;
4017 
4018                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4019                 Rt = Bits32 (opcode, 15, 12);
4020                 Rn = Bits32 (opcode, 19, 16);
4021                 imm32 = Bits32 (opcode, 7, 0);
4022 
4023                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4024                 index = BitIsSet (opcode, 10);
4025                 add = BitIsSet (opcode, 9);
4026                 wback = BitIsSet (opcode, 8);
4027 
4028                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
4029                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
4030                     return false;
4031 
4032                 break;
4033 
4034             default:
4035                 return false;
4036         }
4037         uint32_t base = ReadCoreReg (Rn, &success);
4038         if (!success)
4039             return false;
4040         if (add)
4041             offset_addr = base + imm32;
4042         else
4043             offset_addr = base - imm32;
4044 
4045         address = (index ? offset_addr : base);
4046 
4047         RegisterInfo base_reg;
4048         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4049         if (wback)
4050         {
4051             EmulateInstruction::Context ctx;
4052             if (Rn == 13)
4053             {
4054                 ctx.type = eContextAdjustStackPointer;
4055                 ctx.SetImmediateSigned((int32_t) (offset_addr - base));
4056             }
4057             else if (Rn == GetFramePointerRegisterNumber())
4058             {
4059                 ctx.type = eContextSetFramePointer;
4060                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4061             }
4062             else
4063             {
4064                 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4065                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4066             }
4067 
4068 
4069             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4070                 return false;
4071         }
4072 
4073         // Prepare to write to the Rt register.
4074         EmulateInstruction::Context context;
4075         context.type = EmulateInstruction::eContextRegisterLoad;
4076         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4077 
4078         // Read memory from the address.
4079         data = MemURead(context, address, 4, 0, &success);
4080         if (!success)
4081             return false;
4082 
4083         if (Rt == 15)
4084         {
4085             if (Bits32(address, 1, 0) == 0)
4086             {
4087                 if (!LoadWritePC(context, data))
4088                     return false;
4089             }
4090             else
4091                 return false;
4092         }
4093         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4094         {
4095             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4096                 return false;
4097         }
4098         else
4099             WriteBits32Unknown (Rt);
4100     }
4101     return true;
4102 }
4103 
4104 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4105 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4106 // of those locations can optionally be written back to the base register.
4107 bool
4108 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4109 {
4110 #if 0
4111     if ConditionPassed() then
4112         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4113         address = R[n];
4114 
4115         for i = 0 to 14
4116             if registers<i> == '1' then
4117                 if i == n && wback && i != LowestSetBit(registers) then
4118                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4119                 else
4120                     MemA[address,4] = R[i];
4121                 address = address + 4;
4122 
4123         if registers<15> == '1' then // Only possible for encoding A1
4124             MemA[address,4] = PCStoreValue();
4125         if wback then R[n] = R[n] + 4*BitCount(registers);
4126 #endif
4127 
4128     bool success = false;
4129 
4130     if (ConditionPassed(opcode))
4131     {
4132         uint32_t n;
4133         uint32_t registers = 0;
4134         bool wback;
4135         const uint32_t addr_byte_size = GetAddressByteSize();
4136 
4137         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4138         switch (encoding)
4139         {
4140             case eEncodingT1:
4141                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4142                 n = Bits32 (opcode, 10, 8);
4143                 registers = Bits32 (opcode, 7, 0);
4144                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4145                 wback = true;
4146 
4147                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4148                 if (BitCount (registers) < 1)
4149                     return false;
4150 
4151                 break;
4152 
4153             case eEncodingT2:
4154                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4155                 n = Bits32 (opcode, 19, 16);
4156                 registers = Bits32 (opcode, 15, 0);
4157                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4158                 wback = BitIsSet (opcode, 21);
4159 
4160                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4161                 if ((n == 15) || (BitCount (registers) < 2))
4162                     return false;
4163 
4164                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4165                 if (wback && BitIsSet (registers, n))
4166                     return false;
4167 
4168                 break;
4169 
4170             case eEncodingA1:
4171                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4172                 n = Bits32 (opcode, 19, 16);
4173                 registers = Bits32 (opcode, 15, 0);
4174                 wback = BitIsSet (opcode, 21);
4175 
4176                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4177                 if ((n == 15) || (BitCount (registers) < 1))
4178                     return false;
4179 
4180                 break;
4181 
4182             default:
4183                 return false;
4184         }
4185 
4186         // address = R[n];
4187         int32_t offset = 0;
4188         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4189         if (!success)
4190             return false;
4191 
4192         EmulateInstruction::Context context;
4193         context.type = EmulateInstruction::eContextRegisterStore;
4194         RegisterInfo base_reg;
4195         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4196 
4197         // for i = 0 to 14
4198         uint32_t lowest_set_bit = 14;
4199         for (uint32_t i = 0; i < 14; ++i)
4200         {
4201             // if registers<i> == '1' then
4202             if (BitIsSet (registers, i))
4203             {
4204                   if (i < lowest_set_bit)
4205                       lowest_set_bit = i;
4206                   // if i == n && wback && i != LowestSetBit(registers) then
4207                   if ((i == n) && wback && (i != lowest_set_bit))
4208                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4209                       WriteBits32UnknownToMemory (address + offset);
4210                   else
4211                   {
4212                      // MemA[address,4] = R[i];
4213                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4214                       if (!success)
4215                           return false;
4216 
4217                       RegisterInfo data_reg;
4218                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4219                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4220                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4221                           return false;
4222                   }
4223 
4224                   // address = address + 4;
4225                   offset += addr_byte_size;
4226             }
4227         }
4228 
4229         // if registers<15> == '1' then // Only possible for encoding A1
4230         //     MemA[address,4] = PCStoreValue();
4231         if (BitIsSet (registers, 15))
4232         {
4233             RegisterInfo pc_reg;
4234             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4235             context.SetRegisterPlusOffset (pc_reg, 8);
4236             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4237             if (!success)
4238                 return false;
4239 
4240             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4241                 return false;
4242         }
4243 
4244         // if wback then R[n] = R[n] + 4*BitCount(registers);
4245         if (wback)
4246         {
4247             offset = addr_byte_size * BitCount (registers);
4248             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4249             context.SetImmediateSigned (offset);
4250             addr_t data = address + offset;
4251             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4252                 return false;
4253         }
4254     }
4255     return true;
4256 }
4257 
4258 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4259 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4260 // of those locations can optionally be written back to the base register.
4261 bool
4262 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4263 {
4264 #if 0
4265     if ConditionPassed() then
4266         EncodingSpecificOperations();
4267         address = R[n] - 4*BitCount(registers) + 4;
4268 
4269         for i = 0 to 14
4270             if registers<i> == '1' then
4271                 if i == n && wback && i != LowestSetBit(registers) then
4272                     MemA[address,4] = bits(32) UNKNOWN;
4273                 else
4274                     MemA[address,4] = R[i];
4275                 address = address + 4;
4276 
4277         if registers<15> == '1' then
4278             MemA[address,4] = PCStoreValue();
4279 
4280         if wback then R[n] = R[n] - 4*BitCount(registers);
4281 #endif
4282 
4283     bool success = false;
4284 
4285     if (ConditionPassed(opcode))
4286     {
4287         uint32_t n;
4288         uint32_t registers = 0;
4289         bool wback;
4290         const uint32_t addr_byte_size = GetAddressByteSize();
4291 
4292         // EncodingSpecificOperations();
4293         switch (encoding)
4294         {
4295             case eEncodingA1:
4296                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4297                 n = Bits32 (opcode, 19, 16);
4298                 registers = Bits32 (opcode, 15, 0);
4299                 wback = BitIsSet (opcode, 21);
4300 
4301                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4302                 if ((n == 15) || (BitCount (registers) < 1))
4303                     return false;
4304                 break;
4305             default:
4306                 return false;
4307         }
4308 
4309         // address = R[n] - 4*BitCount(registers) + 4;
4310         int32_t offset = 0;
4311         addr_t Rn = ReadCoreReg (n, &success);
4312         if (!success)
4313             return false;
4314 
4315         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4316 
4317         EmulateInstruction::Context context;
4318         context.type = EmulateInstruction::eContextRegisterStore;
4319         RegisterInfo base_reg;
4320         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4321 
4322         // for i = 0 to 14
4323         uint32_t lowest_bit_set = 14;
4324         for (uint32_t i = 0; i < 14; ++i)
4325         {
4326             // if registers<i> == '1' then
4327             if (BitIsSet (registers, i))
4328             {
4329                 if (i < lowest_bit_set)
4330                     lowest_bit_set = i;
4331                 //if i == n && wback && i != LowestSetBit(registers) then
4332                 if ((i == n) && wback && (i != lowest_bit_set))
4333                     // MemA[address,4] = bits(32) UNKNOWN;
4334                     WriteBits32UnknownToMemory (address + offset);
4335                 else
4336                 {
4337                     // MemA[address,4] = R[i];
4338                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4339                     if (!success)
4340                         return false;
4341 
4342                     RegisterInfo data_reg;
4343                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4344                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4345                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4346                         return false;
4347                 }
4348 
4349                 // address = address + 4;
4350                 offset += addr_byte_size;
4351             }
4352         }
4353 
4354         // if registers<15> == '1' then
4355         //    MemA[address,4] = PCStoreValue();
4356         if (BitIsSet (registers, 15))
4357         {
4358             RegisterInfo pc_reg;
4359             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4360             context.SetRegisterPlusOffset (pc_reg, 8);
4361             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4362             if (!success)
4363                 return false;
4364 
4365             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4366                 return false;
4367         }
4368 
4369         // if wback then R[n] = R[n] - 4*BitCount(registers);
4370         if (wback)
4371         {
4372             offset = (addr_byte_size * BitCount (registers)) * -1;
4373             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4374             context.SetImmediateSigned (offset);
4375             addr_t data = Rn + offset;
4376             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4377                 return false;
4378         }
4379     }
4380     return true;
4381 }
4382 
4383 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4384 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4385 // those locations can optionally be written back to the base register.
4386 bool
4387 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4388 {
4389 #if 0
4390     if ConditionPassed() then
4391         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4392         address = R[n] - 4*BitCount(registers);
4393 
4394         for i = 0 to 14
4395             if registers<i> == '1' then
4396                 if i == n && wback && i != LowestSetBit(registers) then
4397                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4398                 else
4399                     MemA[address,4] = R[i];
4400                 address = address + 4;
4401 
4402         if registers<15> == '1' then // Only possible for encoding A1
4403             MemA[address,4] = PCStoreValue();
4404 
4405         if wback then R[n] = R[n] - 4*BitCount(registers);
4406 #endif
4407 
4408 
4409     bool success = false;
4410 
4411     if (ConditionPassed(opcode))
4412     {
4413         uint32_t n;
4414         uint32_t registers = 0;
4415         bool wback;
4416         const uint32_t addr_byte_size = GetAddressByteSize();
4417 
4418         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4419         switch (encoding)
4420         {
4421             case eEncodingT1:
4422                 // if W == '1' && Rn == '1101' then SEE PUSH;
4423                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4424                 {
4425                     // See PUSH
4426                 }
4427                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4428                 n = Bits32 (opcode, 19, 16);
4429                 registers = Bits32 (opcode, 15, 0);
4430                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4431                 wback = BitIsSet (opcode, 21);
4432                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4433                 if ((n == 15) || BitCount (registers) < 2)
4434                     return false;
4435                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4436                 if (wback && BitIsSet (registers, n))
4437                     return false;
4438                 break;
4439 
4440             case eEncodingA1:
4441                 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH;
4442                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4443                 {
4444                     // See Push
4445                 }
4446                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4447                 n = Bits32 (opcode, 19, 16);
4448                 registers = Bits32 (opcode, 15, 0);
4449                 wback = BitIsSet (opcode, 21);
4450                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4451                 if ((n == 15) || BitCount (registers) < 1)
4452                     return false;
4453                 break;
4454 
4455             default:
4456                 return false;
4457         }
4458 
4459         // address = R[n] - 4*BitCount(registers);
4460 
4461         int32_t offset = 0;
4462         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4463         if (!success)
4464         return false;
4465 
4466         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4467 
4468         EmulateInstruction::Context context;
4469         context.type = EmulateInstruction::eContextRegisterStore;
4470         RegisterInfo base_reg;
4471         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4472 
4473         // for i = 0 to 14
4474         uint32_t lowest_set_bit = 14;
4475         for (uint32_t i = 0; i < 14; ++i)
4476         {
4477             // if registers<i> == '1' then
4478             if (BitIsSet (registers, i))
4479             {
4480                 if (i < lowest_set_bit)
4481                     lowest_set_bit = i;
4482                 // if i == n && wback && i != LowestSetBit(registers) then
4483                 if ((i == n) && wback && (i != lowest_set_bit))
4484                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4485                     WriteBits32UnknownToMemory (address + offset);
4486                 else
4487                 {
4488                     // MemA[address,4] = R[i];
4489                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4490                     if (!success)
4491                         return false;
4492 
4493                     RegisterInfo data_reg;
4494                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4495                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4496                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4497                         return false;
4498                 }
4499 
4500                 // address = address + 4;
4501                 offset += addr_byte_size;
4502             }
4503         }
4504 
4505         // if registers<15> == '1' then // Only possible for encoding A1
4506         //     MemA[address,4] = PCStoreValue();
4507         if (BitIsSet (registers, 15))
4508         {
4509             RegisterInfo pc_reg;
4510             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4511             context.SetRegisterPlusOffset (pc_reg, 8);
4512             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4513             if (!success)
4514                 return false;
4515 
4516             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4517                 return false;
4518         }
4519 
4520         // if wback then R[n] = R[n] - 4*BitCount(registers);
4521         if (wback)
4522         {
4523             offset = (addr_byte_size * BitCount (registers)) * -1;
4524             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4525             context.SetImmediateSigned (offset);
4526             addr_t data = Rn + offset;
4527             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4528                 return false;
4529         }
4530     }
4531     return true;
4532 }
4533 
4534 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4535 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4536 // of those locations can optionally be written back to the base register.
4537 bool
4538 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4539 {
4540 #if 0
4541     if ConditionPassed() then
4542         EncodingSpecificOperations();
4543         address = R[n] + 4;
4544 
4545         for i = 0 to 14
4546             if registers<i> == '1' then
4547                 if i == n && wback && i != LowestSetBit(registers) then
4548                     MemA[address,4] = bits(32) UNKNOWN;
4549                 else
4550                     MemA[address,4] = R[i];
4551                 address = address + 4;
4552 
4553         if registers<15> == '1' then
4554             MemA[address,4] = PCStoreValue();
4555 
4556         if wback then R[n] = R[n] + 4*BitCount(registers);
4557 #endif
4558 
4559     bool success = false;
4560 
4561     if (ConditionPassed(opcode))
4562     {
4563         uint32_t n;
4564         uint32_t registers = 0;
4565         bool wback;
4566         const uint32_t addr_byte_size = GetAddressByteSize();
4567 
4568         // EncodingSpecificOperations();
4569         switch (encoding)
4570         {
4571             case eEncodingA1:
4572                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4573                 n = Bits32 (opcode, 19, 16);
4574                 registers = Bits32 (opcode, 15, 0);
4575                 wback = BitIsSet (opcode, 21);
4576 
4577                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4578                 if ((n == 15) && (BitCount (registers) < 1))
4579                     return false;
4580                 break;
4581             default:
4582                 return false;
4583         }
4584         // address = R[n] + 4;
4585 
4586         int32_t offset = 0;
4587         addr_t Rn = ReadCoreReg (n, &success);
4588         if (!success)
4589             return false;
4590 
4591         addr_t address = Rn + addr_byte_size;
4592 
4593         EmulateInstruction::Context context;
4594         context.type = EmulateInstruction::eContextRegisterStore;
4595         RegisterInfo base_reg;
4596         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4597 
4598         uint32_t lowest_set_bit = 14;
4599         // for i = 0 to 14
4600         for (uint32_t i = 0; i < 14; ++i)
4601         {
4602             // if registers<i> == '1' then
4603             if (BitIsSet (registers, i))
4604             {
4605                 if (i < lowest_set_bit)
4606                     lowest_set_bit = i;
4607                 // if i == n && wback && i != LowestSetBit(registers) then
4608                 if ((i == n) && wback && (i != lowest_set_bit))
4609                     // MemA[address,4] = bits(32) UNKNOWN;
4610                     WriteBits32UnknownToMemory (address + offset);
4611                 // else
4612                 else
4613                 {
4614                     // MemA[address,4] = R[i];
4615                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4616                     if (!success)
4617                         return false;
4618 
4619                     RegisterInfo data_reg;
4620                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4621                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4622                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4623                         return false;
4624                 }
4625 
4626                 // address = address + 4;
4627                 offset += addr_byte_size;
4628             }
4629         }
4630 
4631         // if registers<15> == '1' then
4632             // MemA[address,4] = PCStoreValue();
4633         if (BitIsSet (registers, 15))
4634         {
4635             RegisterInfo pc_reg;
4636             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4637             context.SetRegisterPlusOffset (pc_reg, 8);
4638             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4639             if (!success)
4640             return false;
4641 
4642             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4643                 return false;
4644         }
4645 
4646         // if wback then R[n] = R[n] + 4*BitCount(registers);
4647         if (wback)
4648         {
4649             offset = addr_byte_size * BitCount (registers);
4650             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4651             context.SetImmediateSigned (offset);
4652             addr_t data = Rn + offset;
4653             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4654                 return false;
4655         }
4656     }
4657     return true;
4658 }
4659 
4660 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4661 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4662 bool
4663 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4664 {
4665 #if 0
4666     if ConditionPassed() then
4667         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4668         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4669         address = if index then offset_addr else R[n];
4670         if UnalignedSupport() || address<1:0> == '00' then
4671             MemU[address,4] = R[t];
4672         else // Can only occur before ARMv7
4673             MemU[address,4] = bits(32) UNKNOWN;
4674         if wback then R[n] = offset_addr;
4675 #endif
4676 
4677     bool success = false;
4678 
4679     if (ConditionPassed(opcode))
4680     {
4681         const uint32_t addr_byte_size = GetAddressByteSize();
4682 
4683         uint32_t t;
4684         uint32_t n;
4685         uint32_t imm32;
4686         bool index;
4687         bool add;
4688         bool wback;
4689         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4690         switch (encoding)
4691         {
4692             case eEncodingT1:
4693                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4694                 t = Bits32 (opcode, 2, 0);
4695                 n = Bits32 (opcode, 5, 3);
4696                 imm32 = Bits32 (opcode, 10, 6) << 2;
4697 
4698                 // index = TRUE; add = TRUE; wback = FALSE;
4699                 index = true;
4700                 add = false;
4701                 wback = false;
4702                 break;
4703 
4704             case eEncodingT2:
4705                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4706                 t = Bits32 (opcode, 10, 8);
4707                 n = 13;
4708                 imm32 = Bits32 (opcode, 7, 0) << 2;
4709 
4710                 // index = TRUE; add = TRUE; wback = FALSE;
4711                 index = true;
4712                 add = true;
4713                 wback = false;
4714                 break;
4715 
4716             case eEncodingT3:
4717                 // if Rn == '1111' then UNDEFINED;
4718                 if (Bits32 (opcode, 19, 16) == 15)
4719                     return false;
4720 
4721                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4722                 t = Bits32 (opcode, 15, 12);
4723                 n = Bits32 (opcode, 19, 16);
4724                 imm32 = Bits32 (opcode, 11, 0);
4725 
4726                 // index = TRUE; add = TRUE; wback = FALSE;
4727                 index = true;
4728                 add = true;
4729                 wback = false;
4730 
4731                 // if t == 15 then UNPREDICTABLE;
4732                 if (t == 15)
4733                     return false;
4734                 break;
4735 
4736             case eEncodingT4:
4737                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4738                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4739                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4740                 if ((Bits32 (opcode, 19, 16) == 15)
4741                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4742                     return false;
4743 
4744                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4745                 t = Bits32 (opcode, 15, 12);
4746                 n = Bits32 (opcode, 19, 16);
4747                 imm32 = Bits32 (opcode, 7, 0);
4748 
4749                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4750                 index = BitIsSet (opcode, 10);
4751                 add = BitIsSet (opcode, 9);
4752                 wback = BitIsSet (opcode, 8);
4753 
4754                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4755                 if ((t == 15) || (wback && (n == t)))
4756                     return false;
4757                 break;
4758 
4759             default:
4760                 return false;
4761         }
4762 
4763         addr_t offset_addr;
4764         addr_t address;
4765 
4766         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4767         uint32_t base_address = ReadCoreReg (n, &success);
4768         if (!success)
4769             return false;
4770 
4771         if (add)
4772             offset_addr = base_address + imm32;
4773         else
4774             offset_addr = base_address - imm32;
4775 
4776         // address = if index then offset_addr else R[n];
4777         if (index)
4778             address = offset_addr;
4779         else
4780             address = base_address;
4781 
4782         EmulateInstruction::Context context;
4783         context.type = eContextRegisterStore;
4784         RegisterInfo base_reg;
4785         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4786 
4787         // if UnalignedSupport() || address<1:0> == '00' then
4788         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4789         {
4790             // MemU[address,4] = R[t];
4791             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4792             if (!success)
4793                 return false;
4794 
4795             RegisterInfo data_reg;
4796             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4797             int32_t offset = address - base_address;
4798             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4799             if (!MemUWrite (context, address, data, addr_byte_size))
4800                 return false;
4801         }
4802         else
4803         {
4804             // MemU[address,4] = bits(32) UNKNOWN;
4805             WriteBits32UnknownToMemory (address);
4806         }
4807 
4808         // if wback then R[n] = offset_addr;
4809         if (wback)
4810         {
4811             context.type = eContextRegisterLoad;
4812             context.SetAddress (offset_addr);
4813             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4814                 return false;
4815         }
4816     }
4817     return true;
4818 }
4819 
4820 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4821 // word from a register to memory.   The offset register value can optionally be shifted.
4822 bool
4823 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4824 {
4825 #if 0
4826     if ConditionPassed() then
4827         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4828         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4829         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4830         address = if index then offset_addr else R[n];
4831         if t == 15 then // Only possible for encoding A1
4832             data = PCStoreValue();
4833         else
4834             data = R[t];
4835         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4836             MemU[address,4] = data;
4837         else // Can only occur before ARMv7
4838             MemU[address,4] = bits(32) UNKNOWN;
4839         if wback then R[n] = offset_addr;
4840 #endif
4841 
4842     bool success = false;
4843 
4844     if (ConditionPassed(opcode))
4845     {
4846         const uint32_t addr_byte_size = GetAddressByteSize();
4847 
4848         uint32_t t;
4849         uint32_t n;
4850         uint32_t m;
4851         ARM_ShifterType shift_t;
4852         uint32_t shift_n;
4853         bool index;
4854         bool add;
4855         bool wback;
4856 
4857         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4858         switch (encoding)
4859         {
4860             case eEncodingT1:
4861                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4862                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4863                 t = Bits32 (opcode, 2, 0);
4864                 n = Bits32 (opcode, 5, 3);
4865                 m = Bits32 (opcode, 8, 6);
4866 
4867                 // index = TRUE; add = TRUE; wback = FALSE;
4868                 index = true;
4869                 add = true;
4870                 wback = false;
4871 
4872                 // (shift_t, shift_n) = (SRType_LSL, 0);
4873                 shift_t = SRType_LSL;
4874                 shift_n = 0;
4875                 break;
4876 
4877             case eEncodingT2:
4878                 // if Rn == '1111' then UNDEFINED;
4879                 if (Bits32 (opcode, 19, 16) == 15)
4880                     return false;
4881 
4882                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4883                 t = Bits32 (opcode, 15, 12);
4884                 n = Bits32 (opcode, 19, 16);
4885                 m = Bits32 (opcode, 3, 0);
4886 
4887                 // index = TRUE; add = TRUE; wback = FALSE;
4888                 index = true;
4889                 add = true;
4890                 wback = false;
4891 
4892                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4893                 shift_t = SRType_LSL;
4894                 shift_n = Bits32 (opcode, 5, 4);
4895 
4896                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4897                 if ((t == 15) || (BadReg (m)))
4898                     return false;
4899                 break;
4900 
4901             case eEncodingA1:
4902             {
4903                 // if P == '0' && W == '1' then SEE STRT;
4904                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4905                 t = Bits32 (opcode, 15, 12);
4906                 n = Bits32 (opcode, 19, 16);
4907                 m = Bits32 (opcode, 3, 0);
4908 
4909                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4910                 index = BitIsSet (opcode, 24);
4911                 add = BitIsSet (opcode, 23);
4912                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4913 
4914                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4915                 uint32_t typ = Bits32 (opcode, 6, 5);
4916                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4917                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4918 
4919                 // if m == 15 then UNPREDICTABLE;
4920                 if (m == 15)
4921                     return false;
4922 
4923                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4924                 if (wback && ((n == 15) || (n == t)))
4925                     return false;
4926 
4927                 break;
4928             }
4929             default:
4930                 return false;
4931         }
4932 
4933         addr_t offset_addr;
4934         addr_t address;
4935         int32_t offset = 0;
4936 
4937         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4938         if (!success)
4939             return false;
4940 
4941         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4942         if (!success)
4943             return false;
4944 
4945         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4946         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4947         if (!success)
4948             return false;
4949 
4950         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4951         if (add)
4952             offset_addr = base_address + offset;
4953         else
4954             offset_addr = base_address - offset;
4955 
4956         // address = if index then offset_addr else R[n];
4957         if (index)
4958             address = offset_addr;
4959         else
4960             address = base_address;
4961 
4962         uint32_t data;
4963         // if t == 15 then // Only possible for encoding A1
4964         if (t == 15)
4965             // data = PCStoreValue();
4966             data = ReadCoreReg (PC_REG, &success);
4967         else
4968             // data = R[t];
4969             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4970 
4971         if (!success)
4972             return false;
4973 
4974         EmulateInstruction::Context context;
4975         context.type = eContextRegisterStore;
4976 
4977         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4978         if (UnalignedSupport ()
4979             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4980             || CurrentInstrSet() == eModeARM)
4981         {
4982             // MemU[address,4] = data;
4983 
4984             RegisterInfo base_reg;
4985             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4986 
4987             RegisterInfo data_reg;
4988             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4989 
4990             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4991             if (!MemUWrite (context, address, data, addr_byte_size))
4992                 return false;
4993 
4994         }
4995         else
4996             // MemU[address,4] = bits(32) UNKNOWN;
4997             WriteBits32UnknownToMemory (address);
4998 
4999         // if wback then R[n] = offset_addr;
5000         if (wback)
5001         {
5002             context.type = eContextRegisterLoad;
5003             context.SetAddress (offset_addr);
5004             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5005                 return false;
5006         }
5007 
5008     }
5009     return true;
5010 }
5011 
5012 bool
5013 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
5014 {
5015 #if 0
5016     if ConditionPassed() then
5017         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5018         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5019         address = if index then offset_addr else R[n];
5020         MemU[address,1] = R[t]<7:0>;
5021         if wback then R[n] = offset_addr;
5022 #endif
5023 
5024 
5025     bool success = false;
5026 
5027     if (ConditionPassed(opcode))
5028     {
5029         uint32_t t;
5030         uint32_t n;
5031         uint32_t imm32;
5032         bool index;
5033         bool add;
5034         bool wback;
5035         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5036         switch (encoding)
5037         {
5038             case eEncodingT1:
5039                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5040                 t = Bits32 (opcode, 2, 0);
5041                 n = Bits32 (opcode, 5, 3);
5042                 imm32 = Bits32 (opcode, 10, 6);
5043 
5044                 // index = TRUE; add = TRUE; wback = FALSE;
5045                 index = true;
5046                 add = true;
5047                 wback = false;
5048                 break;
5049 
5050             case eEncodingT2:
5051                 // if Rn == '1111' then UNDEFINED;
5052                 if (Bits32 (opcode, 19, 16) == 15)
5053                     return false;
5054 
5055                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5056                 t = Bits32 (opcode, 15, 12);
5057                 n = Bits32 (opcode, 19, 16);
5058                 imm32 = Bits32 (opcode, 11, 0);
5059 
5060                 // index = TRUE; add = TRUE; wback = FALSE;
5061                 index = true;
5062                 add = true;
5063                 wback = false;
5064 
5065                 // if BadReg(t) then UNPREDICTABLE;
5066                 if (BadReg (t))
5067                     return false;
5068                 break;
5069 
5070             case eEncodingT3:
5071                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5072                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5073                 if (Bits32 (opcode, 19, 16) == 15)
5074                     return false;
5075 
5076                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5077                 t = Bits32 (opcode, 15, 12);
5078                 n = Bits32 (opcode, 19, 16);
5079                 imm32 = Bits32 (opcode, 7, 0);
5080 
5081                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5082                 index = BitIsSet (opcode, 10);
5083                 add = BitIsSet (opcode, 9);
5084                 wback = BitIsSet (opcode, 8);
5085 
5086                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5087                 if ((BadReg (t)) || (wback && (n == t)))
5088                     return false;
5089                 break;
5090 
5091             default:
5092                 return false;
5093         }
5094 
5095         addr_t offset_addr;
5096         addr_t address;
5097         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5098         if (!success)
5099             return false;
5100 
5101         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5102         if (add)
5103             offset_addr = base_address + imm32;
5104         else
5105             offset_addr = base_address - imm32;
5106 
5107         // address = if index then offset_addr else R[n];
5108         if (index)
5109             address = offset_addr;
5110         else
5111             address = base_address;
5112 
5113         // MemU[address,1] = R[t]<7:0>
5114         RegisterInfo base_reg;
5115         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5116 
5117         RegisterInfo data_reg;
5118         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5119 
5120         EmulateInstruction::Context context;
5121         context.type = eContextRegisterStore;
5122         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5123 
5124         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5125         if (!success)
5126             return false;
5127 
5128         data = Bits32 (data, 7, 0);
5129 
5130         if (!MemUWrite (context, address, data, 1))
5131             return false;
5132 
5133         // if wback then R[n] = offset_addr;
5134         if (wback)
5135         {
5136             context.type = eContextRegisterLoad;
5137             context.SetAddress (offset_addr);
5138             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5139                 return false;
5140         }
5141 
5142     }
5143 
5144     return true;
5145 }
5146 
5147 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5148 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5149 bool
5150 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5151 {
5152 #if 0
5153     if ConditionPassed() then
5154         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5155         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5156         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5157         address = if index then offset_addr else R[n];
5158         if UnalignedSupport() || address<0> == '0' then
5159             MemU[address,2] = R[t]<15:0>;
5160         else // Can only occur before ARMv7
5161             MemU[address,2] = bits(16) UNKNOWN;
5162         if wback then R[n] = offset_addr;
5163 #endif
5164 
5165     bool success = false;
5166 
5167     if (ConditionPassed(opcode))
5168     {
5169         uint32_t t;
5170         uint32_t n;
5171         uint32_t m;
5172         bool index;
5173         bool add;
5174         bool wback;
5175         ARM_ShifterType shift_t;
5176         uint32_t shift_n;
5177 
5178         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5179         switch (encoding)
5180         {
5181             case eEncodingT1:
5182                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5183                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5184                 t = Bits32 (opcode, 2, 0);
5185                 n = Bits32 (opcode, 5, 3);
5186                 m = Bits32 (opcode, 8, 6);
5187 
5188                 // index = TRUE; add = TRUE; wback = FALSE;
5189                 index = true;
5190                 add = true;
5191                 wback = false;
5192 
5193                 // (shift_t, shift_n) = (SRType_LSL, 0);
5194                 shift_t = SRType_LSL;
5195                 shift_n = 0;
5196 
5197                 break;
5198 
5199             case eEncodingT2:
5200                 // if Rn == '1111' then UNDEFINED;
5201                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5202                 t = Bits32 (opcode, 15, 12);
5203                 n = Bits32 (opcode, 19, 16);
5204                 m = Bits32 (opcode, 3, 0);
5205                 if (n == 15)
5206                     return false;
5207 
5208                 // index = TRUE; add = TRUE; wback = FALSE;
5209                 index = true;
5210                 add = true;
5211                 wback = false;
5212 
5213                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5214                 shift_t = SRType_LSL;
5215                 shift_n = Bits32 (opcode, 5, 4);
5216 
5217                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5218                 if (BadReg (t) || BadReg (m))
5219                     return false;
5220 
5221                 break;
5222 
5223             case eEncodingA1:
5224                 // if P == '0' && W == '1' then SEE STRHT;
5225                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5226                 t = Bits32 (opcode, 15, 12);
5227                 n = Bits32 (opcode, 19, 16);
5228                 m = Bits32 (opcode, 3, 0);
5229 
5230                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5231                 index = BitIsSet (opcode, 24);
5232                 add = BitIsSet (opcode, 23);
5233                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5234 
5235                 // (shift_t, shift_n) = (SRType_LSL, 0);
5236                 shift_t = SRType_LSL;
5237                 shift_n = 0;
5238 
5239                 // if t == 15 || m == 15 then UNPREDICTABLE;
5240                 if ((t == 15) || (m == 15))
5241                     return false;
5242 
5243                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5244                 if (wback && ((n == 15) || (n == t)))
5245                     return false;
5246 
5247                 break;
5248 
5249             default:
5250                 return false;
5251         }
5252 
5253         uint32_t Rm = ReadCoreReg (m, &success);
5254         if (!success)
5255             return false;
5256 
5257         uint32_t Rn = ReadCoreReg (n, &success);
5258         if (!success)
5259             return false;
5260 
5261         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5262         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5263         if (!success)
5264             return false;
5265 
5266         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5267         addr_t offset_addr;
5268         if (add)
5269             offset_addr = Rn + offset;
5270         else
5271             offset_addr = Rn - offset;
5272 
5273         // address = if index then offset_addr else R[n];
5274         addr_t address;
5275         if (index)
5276             address = offset_addr;
5277         else
5278             address = Rn;
5279 
5280         EmulateInstruction::Context context;
5281         context.type = eContextRegisterStore;
5282         RegisterInfo base_reg;
5283         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5284         RegisterInfo offset_reg;
5285         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5286 
5287         // if UnalignedSupport() || address<0> == '0' then
5288         if (UnalignedSupport() || BitIsClear (address, 0))
5289         {
5290             // MemU[address,2] = R[t]<15:0>;
5291             uint32_t Rt = ReadCoreReg (t, &success);
5292             if (!success)
5293                 return false;
5294 
5295             EmulateInstruction::Context context;
5296             context.type = eContextRegisterStore;
5297             RegisterInfo base_reg;
5298             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5299             RegisterInfo offset_reg;
5300             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5301             RegisterInfo data_reg;
5302             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5303             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5304 
5305             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5306                 return false;
5307         }
5308         else // Can only occur before ARMv7
5309         {
5310             // MemU[address,2] = bits(16) UNKNOWN;
5311         }
5312 
5313         // if wback then R[n] = offset_addr;
5314         if (wback)
5315         {
5316             context.type = eContextAdjustBaseRegister;
5317             context.SetAddress (offset_addr);
5318             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5319                 return false;
5320         }
5321     }
5322 
5323     return true;
5324 }
5325 
5326 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5327 // and writes the result to the destination register.  It can optionally update the condition flags
5328 // based on the result.
5329 bool
5330 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5331 {
5332 #if 0
5333     // ARM pseudo code...
5334     if ConditionPassed() then
5335         EncodingSpecificOperations();
5336         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5337         if d == 15 then         // Can only occur for ARM encoding
5338             ALUWritePC(result); // setflags is always FALSE here
5339         else
5340             R[d] = result;
5341             if setflags then
5342                 APSR.N = result<31>;
5343                 APSR.Z = IsZeroBit(result);
5344                 APSR.C = carry;
5345                 APSR.V = overflow;
5346 #endif
5347 
5348     bool success = false;
5349 
5350     if (ConditionPassed(opcode))
5351     {
5352         uint32_t Rd, Rn;
5353         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5354         bool setflags;
5355         switch (encoding)
5356         {
5357         case eEncodingT1:
5358             Rd = Bits32(opcode, 11, 8);
5359             Rn = Bits32(opcode, 19, 16);
5360             setflags = BitIsSet(opcode, 20);
5361             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5362             if (BadReg(Rd) || BadReg(Rn))
5363                 return false;
5364             break;
5365         case eEncodingA1:
5366             Rd = Bits32(opcode, 15, 12);
5367             Rn = Bits32(opcode, 19, 16);
5368             setflags = BitIsSet(opcode, 20);
5369             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5370 
5371             if (Rd == 15 && setflags)
5372                 return EmulateSUBSPcLrEtc (opcode, encoding);
5373             break;
5374         default:
5375             return false;
5376         }
5377 
5378         // Read the first operand.
5379         int32_t val1 = ReadCoreReg(Rn, &success);
5380         if (!success)
5381             return false;
5382 
5383         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5384 
5385         EmulateInstruction::Context context;
5386         context.type = EmulateInstruction::eContextImmediate;
5387         context.SetNoArgs ();
5388 
5389         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5390             return false;
5391     }
5392     return true;
5393 }
5394 
5395 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5396 // register value, and writes the result to the destination register.  It can optionally update the
5397 // condition flags based on the result.
5398 bool
5399 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5400 {
5401 #if 0
5402     // ARM pseudo code...
5403     if ConditionPassed() then
5404         EncodingSpecificOperations();
5405         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5406         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5407         if d == 15 then         // Can only occur for ARM encoding
5408             ALUWritePC(result); // setflags is always FALSE here
5409         else
5410             R[d] = result;
5411             if setflags then
5412                 APSR.N = result<31>;
5413                 APSR.Z = IsZeroBit(result);
5414                 APSR.C = carry;
5415                 APSR.V = overflow;
5416 #endif
5417 
5418     bool success = false;
5419 
5420     if (ConditionPassed(opcode))
5421     {
5422         uint32_t Rd, Rn, Rm;
5423         ARM_ShifterType shift_t;
5424         uint32_t shift_n; // the shift applied to the value read from Rm
5425         bool setflags;
5426         switch (encoding)
5427         {
5428         case eEncodingT1:
5429             Rd = Rn = Bits32(opcode, 2, 0);
5430             Rm = Bits32(opcode, 5, 3);
5431             setflags = !InITBlock();
5432             shift_t = SRType_LSL;
5433             shift_n = 0;
5434             break;
5435         case eEncodingT2:
5436             Rd = Bits32(opcode, 11, 8);
5437             Rn = Bits32(opcode, 19, 16);
5438             Rm = Bits32(opcode, 3, 0);
5439             setflags = BitIsSet(opcode, 20);
5440             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5441             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5442                 return false;
5443             break;
5444         case eEncodingA1:
5445             Rd = Bits32(opcode, 15, 12);
5446             Rn = Bits32(opcode, 19, 16);
5447             Rm = Bits32(opcode, 3, 0);
5448             setflags = BitIsSet(opcode, 20);
5449             shift_n = DecodeImmShiftARM(opcode, shift_t);
5450 
5451             if (Rd == 15 && setflags)
5452                 return EmulateSUBSPcLrEtc (opcode, encoding);
5453             break;
5454         default:
5455             return false;
5456         }
5457 
5458         // Read the first operand.
5459         int32_t val1 = ReadCoreReg(Rn, &success);
5460         if (!success)
5461             return false;
5462 
5463         // Read the second operand.
5464         int32_t val2 = ReadCoreReg(Rm, &success);
5465         if (!success)
5466             return false;
5467 
5468         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5469         if (!success)
5470             return false;
5471         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5472 
5473         EmulateInstruction::Context context;
5474         context.type = EmulateInstruction::eContextImmediate;
5475         context.SetNoArgs ();
5476 
5477         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5478             return false;
5479     }
5480     return true;
5481 }
5482 
5483 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5484 // and writes the result to the destination register.
5485 bool
5486 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5487 {
5488 #if 0
5489     // ARM pseudo code...
5490     if ConditionPassed() then
5491         EncodingSpecificOperations();
5492         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5493         if d == 15 then         // Can only occur for ARM encodings
5494             ALUWritePC(result);
5495         else
5496             R[d] = result;
5497 #endif
5498 
5499     bool success = false;
5500 
5501     if (ConditionPassed(opcode))
5502     {
5503         uint32_t Rd;
5504         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5505         bool add;
5506         switch (encoding)
5507         {
5508         case eEncodingT1:
5509             Rd = Bits32(opcode, 10, 8);
5510             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5511             add = true;
5512             break;
5513         case eEncodingT2:
5514         case eEncodingT3:
5515             Rd = Bits32(opcode, 11, 8);
5516             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5517             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5518             if (BadReg(Rd))
5519                 return false;
5520             break;
5521         case eEncodingA1:
5522         case eEncodingA2:
5523             Rd = Bits32(opcode, 15, 12);
5524             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5525             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5526             break;
5527         default:
5528             return false;
5529         }
5530 
5531         // Read the PC value.
5532         uint32_t pc = ReadCoreReg(PC_REG, &success);
5533         if (!success)
5534             return false;
5535 
5536         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5537 
5538         EmulateInstruction::Context context;
5539         context.type = EmulateInstruction::eContextImmediate;
5540         context.SetNoArgs ();
5541 
5542         if (!WriteCoreReg(context, result, Rd))
5543             return false;
5544     }
5545     return true;
5546 }
5547 
5548 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5549 // to the destination register.  It can optionally update the condition flags based on the result.
5550 bool
5551 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5552 {
5553 #if 0
5554     // ARM pseudo code...
5555     if ConditionPassed() then
5556         EncodingSpecificOperations();
5557         result = R[n] AND imm32;
5558         if d == 15 then         // Can only occur for ARM encoding
5559             ALUWritePC(result); // setflags is always FALSE here
5560         else
5561             R[d] = result;
5562             if setflags then
5563                 APSR.N = result<31>;
5564                 APSR.Z = IsZeroBit(result);
5565                 APSR.C = carry;
5566                 // APSR.V unchanged
5567 #endif
5568 
5569     bool success = false;
5570 
5571     if (ConditionPassed(opcode))
5572     {
5573         uint32_t Rd, Rn;
5574         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5575         bool setflags;
5576         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5577         switch (encoding)
5578         {
5579         case eEncodingT1:
5580             Rd = Bits32(opcode, 11, 8);
5581             Rn = Bits32(opcode, 19, 16);
5582             setflags = BitIsSet(opcode, 20);
5583             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5584             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5585             if (Rd == 15 && setflags)
5586                 return EmulateTSTImm(opcode, eEncodingT1);
5587             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5588                 return false;
5589             break;
5590         case eEncodingA1:
5591             Rd = Bits32(opcode, 15, 12);
5592             Rn = Bits32(opcode, 19, 16);
5593             setflags = BitIsSet(opcode, 20);
5594             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5595 
5596             if (Rd == 15 && setflags)
5597                 return EmulateSUBSPcLrEtc (opcode, encoding);
5598             break;
5599         default:
5600             return false;
5601         }
5602 
5603         // Read the first operand.
5604         uint32_t val1 = ReadCoreReg(Rn, &success);
5605         if (!success)
5606             return false;
5607 
5608         uint32_t result = val1 & imm32;
5609 
5610         EmulateInstruction::Context context;
5611         context.type = EmulateInstruction::eContextImmediate;
5612         context.SetNoArgs ();
5613 
5614         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5615             return false;
5616     }
5617     return true;
5618 }
5619 
5620 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5621 // and writes the result to the destination register.  It can optionally update the condition flags
5622 // based on the result.
5623 bool
5624 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5625 {
5626 #if 0
5627     // ARM pseudo code...
5628     if ConditionPassed() then
5629         EncodingSpecificOperations();
5630         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5631         result = R[n] AND shifted;
5632         if d == 15 then         // Can only occur for ARM encoding
5633             ALUWritePC(result); // setflags is always FALSE here
5634         else
5635             R[d] = result;
5636             if setflags then
5637                 APSR.N = result<31>;
5638                 APSR.Z = IsZeroBit(result);
5639                 APSR.C = carry;
5640                 // APSR.V unchanged
5641 #endif
5642 
5643     bool success = false;
5644 
5645     if (ConditionPassed(opcode))
5646     {
5647         uint32_t Rd, Rn, Rm;
5648         ARM_ShifterType shift_t;
5649         uint32_t shift_n; // the shift applied to the value read from Rm
5650         bool setflags;
5651         uint32_t carry;
5652         switch (encoding)
5653         {
5654         case eEncodingT1:
5655             Rd = Rn = Bits32(opcode, 2, 0);
5656             Rm = Bits32(opcode, 5, 3);
5657             setflags = !InITBlock();
5658             shift_t = SRType_LSL;
5659             shift_n = 0;
5660             break;
5661         case eEncodingT2:
5662             Rd = Bits32(opcode, 11, 8);
5663             Rn = Bits32(opcode, 19, 16);
5664             Rm = Bits32(opcode, 3, 0);
5665             setflags = BitIsSet(opcode, 20);
5666             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5667             // if Rd == '1111' && S == '1' then SEE TST (register);
5668             if (Rd == 15 && setflags)
5669                 return EmulateTSTReg(opcode, eEncodingT2);
5670             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5671                 return false;
5672             break;
5673         case eEncodingA1:
5674             Rd = Bits32(opcode, 15, 12);
5675             Rn = Bits32(opcode, 19, 16);
5676             Rm = Bits32(opcode, 3, 0);
5677             setflags = BitIsSet(opcode, 20);
5678             shift_n = DecodeImmShiftARM(opcode, shift_t);
5679 
5680             if (Rd == 15 && setflags)
5681                 return EmulateSUBSPcLrEtc (opcode, encoding);
5682             break;
5683         default:
5684             return false;
5685         }
5686 
5687         // Read the first operand.
5688         uint32_t val1 = ReadCoreReg(Rn, &success);
5689         if (!success)
5690             return false;
5691 
5692         // Read the second operand.
5693         uint32_t val2 = ReadCoreReg(Rm, &success);
5694         if (!success)
5695             return false;
5696 
5697         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5698         if (!success)
5699             return false;
5700         uint32_t result = val1 & shifted;
5701 
5702         EmulateInstruction::Context context;
5703         context.type = EmulateInstruction::eContextImmediate;
5704         context.SetNoArgs ();
5705 
5706         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5707             return false;
5708     }
5709     return true;
5710 }
5711 
5712 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5713 // immediate value, and writes the result to the destination register.  It can optionally update the
5714 // condition flags based on the result.
5715 bool
5716 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5717 {
5718 #if 0
5719     // ARM pseudo code...
5720     if ConditionPassed() then
5721         EncodingSpecificOperations();
5722         result = R[n] AND NOT(imm32);
5723         if d == 15 then         // Can only occur for ARM encoding
5724             ALUWritePC(result); // setflags is always FALSE here
5725         else
5726             R[d] = result;
5727             if setflags then
5728                 APSR.N = result<31>;
5729                 APSR.Z = IsZeroBit(result);
5730                 APSR.C = carry;
5731                 // APSR.V unchanged
5732 #endif
5733 
5734     bool success = false;
5735 
5736     if (ConditionPassed(opcode))
5737     {
5738         uint32_t Rd, Rn;
5739         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5740         bool setflags;
5741         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5742         switch (encoding)
5743         {
5744         case eEncodingT1:
5745             Rd = Bits32(opcode, 11, 8);
5746             Rn = Bits32(opcode, 19, 16);
5747             setflags = BitIsSet(opcode, 20);
5748             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5749             if (BadReg(Rd) || BadReg(Rn))
5750                 return false;
5751             break;
5752         case eEncodingA1:
5753             Rd = Bits32(opcode, 15, 12);
5754             Rn = Bits32(opcode, 19, 16);
5755             setflags = BitIsSet(opcode, 20);
5756             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5757 
5758             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5759             if (Rd == 15 && setflags)
5760                 return EmulateSUBSPcLrEtc (opcode, encoding);
5761             break;
5762         default:
5763             return false;
5764         }
5765 
5766         // Read the first operand.
5767         uint32_t val1 = ReadCoreReg(Rn, &success);
5768         if (!success)
5769             return false;
5770 
5771         uint32_t result = val1 & ~imm32;
5772 
5773         EmulateInstruction::Context context;
5774         context.type = EmulateInstruction::eContextImmediate;
5775         context.SetNoArgs ();
5776 
5777         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5778             return false;
5779     }
5780     return true;
5781 }
5782 
5783 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5784 // optionally-shifted register value, and writes the result to the destination register.
5785 // It can optionally update the condition flags based on the result.
5786 bool
5787 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5788 {
5789 #if 0
5790     // ARM pseudo code...
5791     if ConditionPassed() then
5792         EncodingSpecificOperations();
5793         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5794         result = R[n] AND NOT(shifted);
5795         if d == 15 then         // Can only occur for ARM encoding
5796             ALUWritePC(result); // setflags is always FALSE here
5797         else
5798             R[d] = result;
5799             if setflags then
5800                 APSR.N = result<31>;
5801                 APSR.Z = IsZeroBit(result);
5802                 APSR.C = carry;
5803                 // APSR.V unchanged
5804 #endif
5805 
5806     bool success = false;
5807 
5808     if (ConditionPassed(opcode))
5809     {
5810         uint32_t Rd, Rn, Rm;
5811         ARM_ShifterType shift_t;
5812         uint32_t shift_n; // the shift applied to the value read from Rm
5813         bool setflags;
5814         uint32_t carry;
5815         switch (encoding)
5816         {
5817         case eEncodingT1:
5818             Rd = Rn = Bits32(opcode, 2, 0);
5819             Rm = Bits32(opcode, 5, 3);
5820             setflags = !InITBlock();
5821             shift_t = SRType_LSL;
5822             shift_n = 0;
5823             break;
5824         case eEncodingT2:
5825             Rd = Bits32(opcode, 11, 8);
5826             Rn = Bits32(opcode, 19, 16);
5827             Rm = Bits32(opcode, 3, 0);
5828             setflags = BitIsSet(opcode, 20);
5829             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5830             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5831                 return false;
5832             break;
5833         case eEncodingA1:
5834             Rd = Bits32(opcode, 15, 12);
5835             Rn = Bits32(opcode, 19, 16);
5836             Rm = Bits32(opcode, 3, 0);
5837             setflags = BitIsSet(opcode, 20);
5838             shift_n = DecodeImmShiftARM(opcode, shift_t);
5839 
5840             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5841             if (Rd == 15 && setflags)
5842                 return EmulateSUBSPcLrEtc (opcode, encoding);
5843             break;
5844         default:
5845             return false;
5846         }
5847 
5848         // Read the first operand.
5849         uint32_t val1 = ReadCoreReg(Rn, &success);
5850         if (!success)
5851             return false;
5852 
5853         // Read the second operand.
5854         uint32_t val2 = ReadCoreReg(Rm, &success);
5855         if (!success)
5856             return false;
5857 
5858         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5859         if (!success)
5860             return false;
5861         uint32_t result = val1 & ~shifted;
5862 
5863         EmulateInstruction::Context context;
5864         context.type = EmulateInstruction::eContextImmediate;
5865         context.SetNoArgs ();
5866 
5867         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5868             return false;
5869     }
5870     return true;
5871 }
5872 
5873 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5874 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5875 bool
5876 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5877 {
5878 #if 0
5879     if ConditionPassed() then
5880         EncodingSpecificOperations();
5881         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5882         address = if index then offset_addr else R[n];
5883         data = MemU[address,4];
5884         if wback then R[n] = offset_addr;
5885         if t == 15 then
5886             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5887         elsif UnalignedSupport() || address<1:0> = '00' then
5888             R[t] = data;
5889         else // Can only apply before ARMv7
5890             R[t] = ROR(data, 8*UInt(address<1:0>));
5891 #endif
5892 
5893     bool success = false;
5894 
5895     if (ConditionPassed(opcode))
5896     {
5897         const uint32_t addr_byte_size = GetAddressByteSize();
5898 
5899         uint32_t t;
5900         uint32_t n;
5901         uint32_t imm32;
5902         bool index;
5903         bool add;
5904         bool wback;
5905 
5906         switch (encoding)
5907         {
5908             case eEncodingA1:
5909                 // if Rn == '1111' then SEE LDR (literal);
5910                 // if P == '0' && W == '1' then SEE LDRT;
5911                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5912                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5913                 t = Bits32 (opcode, 15, 12);
5914                 n = Bits32 (opcode, 19, 16);
5915                 imm32 = Bits32 (opcode, 11, 0);
5916 
5917                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5918                 index = BitIsSet (opcode, 24);
5919                 add = BitIsSet (opcode, 23);
5920                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5921 
5922                 // if wback && n == t then UNPREDICTABLE;
5923                 if (wback && (n == t))
5924                     return false;
5925 
5926                 break;
5927 
5928             default:
5929                 return false;
5930         }
5931 
5932         addr_t address;
5933         addr_t offset_addr;
5934         addr_t base_address = ReadCoreReg (n, &success);
5935         if (!success)
5936             return false;
5937 
5938         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5939         if (add)
5940             offset_addr = base_address + imm32;
5941         else
5942             offset_addr = base_address - imm32;
5943 
5944         // address = if index then offset_addr else R[n];
5945         if (index)
5946             address = offset_addr;
5947         else
5948             address = base_address;
5949 
5950         // data = MemU[address,4];
5951 
5952         RegisterInfo base_reg;
5953         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5954 
5955         EmulateInstruction::Context context;
5956         context.type = eContextRegisterLoad;
5957         context.SetRegisterPlusOffset (base_reg, address - base_address);
5958 
5959         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5960         if (!success)
5961             return false;
5962 
5963         // if wback then R[n] = offset_addr;
5964         if (wback)
5965         {
5966             context.type = eContextAdjustBaseRegister;
5967             context.SetAddress (offset_addr);
5968             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5969                 return false;
5970         }
5971 
5972         // if t == 15 then
5973         if (t == 15)
5974         {
5975             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5976             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5977             {
5978                 // LoadWritePC (data);
5979                 context.type = eContextRegisterLoad;
5980                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5981                 LoadWritePC (context, data);
5982             }
5983             else
5984                   return false;
5985         }
5986         // elsif UnalignedSupport() || address<1:0> = '00' then
5987         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5988         {
5989             // R[t] = data;
5990             context.type = eContextRegisterLoad;
5991             context.SetRegisterPlusOffset (base_reg, address - base_address);
5992             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5993                 return false;
5994         }
5995         // else // Can only apply before ARMv7
5996         else
5997         {
5998             // R[t] = ROR(data, 8*UInt(address<1:0>));
5999             data = ROR (data, Bits32 (address, 1, 0), &success);
6000             if (!success)
6001                 return false;
6002             context.type = eContextRegisterLoad;
6003             context.SetImmediate (data);
6004             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6005                 return false;
6006         }
6007 
6008     }
6009     return true;
6010 }
6011 
6012 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
6013 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
6014 bool
6015 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
6016 {
6017 #if 0
6018     if ConditionPassed() then
6019         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6020         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6021         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6022         address = if index then offset_addr else R[n];
6023         data = MemU[address,4];
6024         if wback then R[n] = offset_addr;
6025         if t == 15 then
6026             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6027         elsif UnalignedSupport() || address<1:0> = '00' then
6028             R[t] = data;
6029         else // Can only apply before ARMv7
6030             if CurrentInstrSet() == InstrSet_ARM then
6031                 R[t] = ROR(data, 8*UInt(address<1:0>));
6032             else
6033                 R[t] = bits(32) UNKNOWN;
6034 #endif
6035 
6036     bool success = false;
6037 
6038     if (ConditionPassed(opcode))
6039     {
6040         const uint32_t addr_byte_size = GetAddressByteSize();
6041 
6042         uint32_t t;
6043         uint32_t n;
6044         uint32_t m;
6045         bool index;
6046         bool add;
6047         bool wback;
6048         ARM_ShifterType shift_t;
6049         uint32_t shift_n;
6050 
6051         switch (encoding)
6052         {
6053             case eEncodingT1:
6054                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6055                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6056                 t = Bits32 (opcode, 2, 0);
6057                 n = Bits32 (opcode, 5, 3);
6058                 m = Bits32 (opcode, 8, 6);
6059 
6060                 // index = TRUE; add = TRUE; wback = FALSE;
6061                 index = true;
6062                 add = true;
6063                 wback = false;
6064 
6065                 // (shift_t, shift_n) = (SRType_LSL, 0);
6066                 shift_t = SRType_LSL;
6067                 shift_n = 0;
6068 
6069                 break;
6070 
6071             case eEncodingT2:
6072                 // if Rn == '1111' then SEE LDR (literal);
6073                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6074                 t = Bits32 (opcode, 15, 12);
6075                 n = Bits32 (opcode, 19, 16);
6076                 m = Bits32 (opcode, 3, 0);
6077 
6078                 // index = TRUE; add = TRUE; wback = FALSE;
6079                 index = true;
6080                 add = true;
6081                 wback = false;
6082 
6083                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6084                 shift_t = SRType_LSL;
6085                 shift_n = Bits32 (opcode, 5, 4);
6086 
6087                 // if BadReg(m) then UNPREDICTABLE;
6088                 if (BadReg (m))
6089                     return false;
6090 
6091                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6092                 if ((t == 15) && InITBlock() && !LastInITBlock())
6093                     return false;
6094 
6095                 break;
6096 
6097             case eEncodingA1:
6098             {
6099                 // if P == '0' && W == '1' then SEE LDRT;
6100                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6101                 t = Bits32 (opcode, 15, 12);
6102                 n = Bits32 (opcode, 19, 16);
6103                 m = Bits32 (opcode, 3, 0);
6104 
6105                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6106                 index = BitIsSet (opcode, 24);
6107                 add = BitIsSet (opcode, 23);
6108                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6109 
6110                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6111                 uint32_t type = Bits32 (opcode, 6, 5);
6112                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6113                 shift_n = DecodeImmShift (type, imm5, shift_t);
6114 
6115                 // if m == 15 then UNPREDICTABLE;
6116                 if (m == 15)
6117                     return false;
6118 
6119                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6120                 if (wback && ((n == 15) || (n == t)))
6121                     return false;
6122             }
6123                 break;
6124 
6125 
6126             default:
6127                 return false;
6128         }
6129 
6130         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6131         if (!success)
6132             return false;
6133 
6134         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6135         if (!success)
6136             return false;
6137 
6138         addr_t offset_addr;
6139         addr_t address;
6140 
6141         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6142         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6143         if (!success)
6144             return false;
6145 
6146         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6147         if (add)
6148             offset_addr = Rn + offset;
6149         else
6150             offset_addr = Rn - offset;
6151 
6152         // address = if index then offset_addr else R[n];
6153             if (index)
6154                 address = offset_addr;
6155             else
6156                 address = Rn;
6157 
6158         // data = MemU[address,4];
6159         RegisterInfo base_reg;
6160         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6161 
6162         EmulateInstruction::Context context;
6163         context.type = eContextRegisterLoad;
6164         context.SetRegisterPlusOffset (base_reg, address - Rn);
6165 
6166         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6167         if (!success)
6168             return false;
6169 
6170         // if wback then R[n] = offset_addr;
6171         if (wback)
6172         {
6173             context.type = eContextAdjustBaseRegister;
6174             context.SetAddress (offset_addr);
6175             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6176                 return false;
6177         }
6178 
6179         // if t == 15 then
6180         if (t == 15)
6181         {
6182             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6183             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6184             {
6185                 context.type = eContextRegisterLoad;
6186                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6187                 LoadWritePC (context, data);
6188             }
6189             else
6190                 return false;
6191         }
6192         // elsif UnalignedSupport() || address<1:0> = '00' then
6193         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6194         {
6195             // R[t] = data;
6196             context.type = eContextRegisterLoad;
6197             context.SetRegisterPlusOffset (base_reg, address - Rn);
6198             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6199                 return false;
6200         }
6201         else // Can only apply before ARMv7
6202         {
6203             // if CurrentInstrSet() == InstrSet_ARM then
6204             if (CurrentInstrSet () == eModeARM)
6205             {
6206                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6207                 data = ROR (data, Bits32 (address, 1, 0), &success);
6208                 if (!success)
6209                     return false;
6210                 context.type = eContextRegisterLoad;
6211                 context.SetImmediate (data);
6212                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6213                     return false;
6214             }
6215             else
6216             {
6217                 // R[t] = bits(32) UNKNOWN;
6218                 WriteBits32Unknown (t);
6219             }
6220         }
6221     }
6222     return true;
6223 }
6224 
6225 // LDRB (immediate, Thumb)
6226 bool
6227 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6228 {
6229 #if 0
6230     if ConditionPassed() then
6231         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6232         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6233         address = if index then offset_addr else R[n];
6234         R[t] = ZeroExtend(MemU[address,1], 32);
6235         if wback then R[n] = offset_addr;
6236 #endif
6237 
6238     bool success = false;
6239 
6240     if (ConditionPassed(opcode))
6241     {
6242         uint32_t t;
6243         uint32_t n;
6244         uint32_t imm32;
6245         bool index;
6246         bool add;
6247         bool wback;
6248 
6249         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6250         switch (encoding)
6251         {
6252             case eEncodingT1:
6253                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6254                 t = Bits32 (opcode, 2, 0);
6255                 n = Bits32 (opcode, 5, 3);
6256                 imm32 = Bits32 (opcode, 10, 6);
6257 
6258                 // index = TRUE; add = TRUE; wback = FALSE;
6259                 index = true;
6260                 add = true;
6261                 wback= false;
6262 
6263                 break;
6264 
6265             case eEncodingT2:
6266                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6267                 t = Bits32 (opcode, 15, 12);
6268                 n = Bits32 (opcode, 19, 16);
6269                 imm32 = Bits32 (opcode, 11, 0);
6270 
6271                 // index = TRUE; add = TRUE; wback = FALSE;
6272                 index = true;
6273                 add = true;
6274                 wback = false;
6275 
6276                 // if Rt == '1111' then SEE PLD;
6277                 if (t == 15)
6278                     return false; // PLD is not implemented yet
6279 
6280                 // if Rn == '1111' then SEE LDRB (literal);
6281                 if (n == 15)
6282                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6283 
6284                 // if t == 13 then UNPREDICTABLE;
6285                 if (t == 13)
6286                     return false;
6287 
6288                 break;
6289 
6290             case eEncodingT3:
6291                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6292                 // if P == '0' && W == '0' then UNDEFINED;
6293                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6294                     return false;
6295 
6296                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6297                 t = Bits32 (opcode, 15, 12);
6298                 n = Bits32 (opcode, 19, 16);
6299                 imm32 = Bits32 (opcode, 7, 0);
6300 
6301                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6302                 index = BitIsSet (opcode, 10);
6303                 add = BitIsSet (opcode, 9);
6304                 wback = BitIsSet (opcode, 8);
6305 
6306                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6307                 if (t == 15)
6308                     return false; // PLD is not implemented yet
6309 
6310                 // if Rn == '1111' then SEE LDRB (literal);
6311                 if (n == 15)
6312                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6313 
6314                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6315                 if (BadReg (t) || (wback && (n == t)))
6316                     return false;
6317 
6318                 break;
6319 
6320             default:
6321                 return false;
6322         }
6323 
6324         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6325         if (!success)
6326             return false;
6327 
6328         addr_t address;
6329         addr_t offset_addr;
6330 
6331         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6332         if (add)
6333             offset_addr = Rn + imm32;
6334         else
6335             offset_addr = Rn - imm32;
6336 
6337         // address = if index then offset_addr else R[n];
6338         if (index)
6339             address = offset_addr;
6340         else
6341             address = Rn;
6342 
6343         // R[t] = ZeroExtend(MemU[address,1], 32);
6344         RegisterInfo base_reg;
6345         RegisterInfo data_reg;
6346         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6347         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6348 
6349         EmulateInstruction::Context context;
6350         context.type = eContextRegisterLoad;
6351         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6352 
6353         uint64_t data = MemURead (context, address, 1, 0, &success);
6354         if (!success)
6355             return false;
6356 
6357         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6358             return false;
6359 
6360         // if wback then R[n] = offset_addr;
6361         if (wback)
6362         {
6363             context.type = eContextAdjustBaseRegister;
6364             context.SetAddress (offset_addr);
6365             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6366                 return false;
6367         }
6368     }
6369     return true;
6370 }
6371 
6372 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6373 // zero-extends it to form a 32-bit word and writes it to a register.
6374 bool
6375 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6376 {
6377 #if 0
6378     if ConditionPassed() then
6379         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6380         base = Align(PC,4);
6381         address = if add then (base + imm32) else (base - imm32);
6382         R[t] = ZeroExtend(MemU[address,1], 32);
6383 #endif
6384 
6385     bool success = false;
6386 
6387     if (ConditionPassed(opcode))
6388     {
6389         uint32_t t;
6390         uint32_t imm32;
6391         bool add;
6392         switch (encoding)
6393         {
6394             case eEncodingT1:
6395                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6396                 t = Bits32 (opcode, 15, 12);
6397                 imm32 = Bits32 (opcode, 11, 0);
6398                 add = BitIsSet (opcode, 23);
6399 
6400                 // if Rt == '1111' then SEE PLD;
6401                 if (t == 15)
6402                     return false; // PLD is not implemented yet
6403 
6404                 // if t == 13 then UNPREDICTABLE;
6405                 if (t == 13)
6406                     return false;
6407 
6408                 break;
6409 
6410             case eEncodingA1:
6411                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6412                 t = Bits32 (opcode, 15, 12);
6413                 imm32 = Bits32 (opcode, 11, 0);
6414                 add = BitIsSet (opcode, 23);
6415 
6416                 // if t == 15 then UNPREDICTABLE;
6417                 if (t == 15)
6418                     return false;
6419                 break;
6420 
6421             default:
6422                 return false;
6423         }
6424 
6425         // base = Align(PC,4);
6426         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6427         if (!success)
6428             return false;
6429 
6430         uint32_t base = AlignPC (pc_val);
6431 
6432         addr_t address;
6433         // address = if add then (base + imm32) else (base - imm32);
6434         if (add)
6435             address = base + imm32;
6436         else
6437             address = base - imm32;
6438 
6439         // R[t] = ZeroExtend(MemU[address,1], 32);
6440         EmulateInstruction::Context context;
6441         context.type = eContextRelativeBranchImmediate;
6442         context.SetImmediate (address - base);
6443 
6444         uint64_t data = MemURead (context, address, 1, 0, &success);
6445         if (!success)
6446             return false;
6447 
6448         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6449             return false;
6450     }
6451     return true;
6452 }
6453 
6454 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6455 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6456 // optionally be shifted.
6457 bool
6458 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6459 {
6460 #if 0
6461     if ConditionPassed() then
6462         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6463         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6464         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6465         address = if index then offset_addr else R[n];
6466         R[t] = ZeroExtend(MemU[address,1],32);
6467         if wback then R[n] = offset_addr;
6468 #endif
6469 
6470     bool success = false;
6471 
6472     if (ConditionPassed(opcode))
6473     {
6474         uint32_t t;
6475         uint32_t n;
6476         uint32_t m;
6477         bool index;
6478         bool add;
6479         bool wback;
6480         ARM_ShifterType shift_t;
6481         uint32_t shift_n;
6482 
6483         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6484         switch (encoding)
6485         {
6486             case eEncodingT1:
6487                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6488                 t = Bits32 (opcode, 2, 0);
6489                 n = Bits32 (opcode, 5, 3);
6490                 m = Bits32 (opcode, 8, 6);
6491 
6492                 // index = TRUE; add = TRUE; wback = FALSE;
6493                 index = true;
6494                 add = true;
6495                 wback = false;
6496 
6497                 // (shift_t, shift_n) = (SRType_LSL, 0);
6498                 shift_t = SRType_LSL;
6499                 shift_n = 0;
6500                 break;
6501 
6502             case eEncodingT2:
6503                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6504                 t = Bits32 (opcode, 15, 12);
6505                 n = Bits32 (opcode, 19, 16);
6506                 m = Bits32 (opcode, 3, 0);
6507 
6508                 // index = TRUE; add = TRUE; wback = FALSE;
6509                 index = true;
6510                 add = true;
6511                 wback = false;
6512 
6513                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6514                 shift_t = SRType_LSL;
6515                 shift_n = Bits32 (opcode, 5, 4);
6516 
6517                 // if Rt == '1111' then SEE PLD;
6518                 if (t == 15)
6519                     return false; // PLD is not implemented yet
6520 
6521                 // if Rn == '1111' then SEE LDRB (literal);
6522                 if (n == 15)
6523                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6524 
6525                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6526                 if ((t == 13) || BadReg (m))
6527                     return false;
6528                 break;
6529 
6530             case eEncodingA1:
6531             {
6532                 // if P == '0' && W == '1' then SEE LDRBT;
6533                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6534                 t = Bits32 (opcode, 15, 12);
6535                 n = Bits32 (opcode, 19, 16);
6536                 m = Bits32 (opcode, 3, 0);
6537 
6538                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6539                 index = BitIsSet (opcode, 24);
6540                 add = BitIsSet (opcode, 23);
6541                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6542 
6543                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6544                 uint32_t type = Bits32 (opcode, 6, 5);
6545                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6546                 shift_n = DecodeImmShift (type, imm5, shift_t);
6547 
6548                 // if t == 15 || m == 15 then UNPREDICTABLE;
6549                 if ((t == 15) || (m == 15))
6550                     return false;
6551 
6552                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6553                 if (wback && ((n == 15) || (n == t)))
6554                     return false;
6555             }
6556                 break;
6557 
6558             default:
6559                 return false;
6560         }
6561 
6562         addr_t offset_addr;
6563         addr_t address;
6564 
6565         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6566         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6567         if (!success)
6568             return false;
6569 
6570         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6571         if (!success)
6572             return false;
6573 
6574         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6575         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6576         if (!success)
6577             return false;
6578 
6579         if (add)
6580             offset_addr = Rn + offset;
6581         else
6582             offset_addr = Rn - offset;
6583 
6584         // address = if index then offset_addr else R[n];
6585         if (index)
6586             address = offset_addr;
6587         else
6588             address = Rn;
6589 
6590         // R[t] = ZeroExtend(MemU[address,1],32);
6591         RegisterInfo base_reg;
6592         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6593 
6594         EmulateInstruction::Context context;
6595         context.type = eContextRegisterLoad;
6596         context.SetRegisterPlusOffset (base_reg, address - Rn);
6597 
6598         uint64_t data = MemURead (context, address, 1, 0, &success);
6599         if (!success)
6600             return false;
6601 
6602         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6603             return false;
6604 
6605         // if wback then R[n] = offset_addr;
6606         if (wback)
6607         {
6608             context.type = eContextAdjustBaseRegister;
6609             context.SetAddress (offset_addr);
6610             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6611                 return false;
6612         }
6613     }
6614     return true;
6615 }
6616 
6617 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6618 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6619 // post-indexed, or pre-indexed addressing.
6620 bool
6621 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6622 {
6623 #if 0
6624     if ConditionPassed() then
6625         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6626         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6627         address = if index then offset_addr else R[n];
6628         data = MemU[address,2];
6629         if wback then R[n] = offset_addr;
6630         if UnalignedSupport() || address<0> = '0' then
6631             R[t] = ZeroExtend(data, 32);
6632         else // Can only apply before ARMv7
6633             R[t] = bits(32) UNKNOWN;
6634 #endif
6635 
6636 
6637     bool success = false;
6638 
6639     if (ConditionPassed(opcode))
6640     {
6641         uint32_t t;
6642         uint32_t n;
6643         uint32_t imm32;
6644         bool index;
6645         bool add;
6646         bool wback;
6647 
6648         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6649         switch (encoding)
6650         {
6651             case eEncodingT1:
6652                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6653                 t = Bits32 (opcode, 2, 0);
6654                 n = Bits32 (opcode, 5, 3);
6655                 imm32 = Bits32 (opcode, 10, 6) << 1;
6656 
6657                 // index = TRUE; add = TRUE; wback = FALSE;
6658                 index = true;
6659                 add = true;
6660                 wback = false;
6661 
6662                 break;
6663 
6664             case eEncodingT2:
6665                 // if Rt == '1111' then SEE "Unallocated memory hints";
6666                 // if Rn == '1111' then SEE LDRH (literal);
6667                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6668                 t = Bits32 (opcode, 15, 12);
6669                 n = Bits32 (opcode, 19, 16);
6670                 imm32 = Bits32 (opcode, 11, 0);
6671 
6672                 // index = TRUE; add = TRUE; wback = FALSE;
6673                 index = true;
6674                 add = true;
6675                 wback = false;
6676 
6677                 // if t == 13 then UNPREDICTABLE;
6678                 if (t == 13)
6679                     return false;
6680                 break;
6681 
6682             case eEncodingT3:
6683                 // if Rn == '1111' then SEE LDRH (literal);
6684                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6685                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6686                 // if P == '0' && W == '0' then UNDEFINED;
6687                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6688                     return false;
6689 
6690                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6691                 t = Bits32 (opcode, 15, 12);
6692                 n = Bits32 (opcode, 19, 16);
6693                 imm32 = Bits32 (opcode, 7, 0);
6694 
6695                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6696                 index = BitIsSet (opcode, 10);
6697                 add = BitIsSet (opcode, 9);
6698                 wback = BitIsSet (opcode, 8);
6699 
6700                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6701                 if (BadReg (t) || (wback && (n == t)))
6702                     return false;
6703                 break;
6704 
6705             default:
6706                 return false;
6707         }
6708 
6709         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6710         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6711         if (!success)
6712             return false;
6713 
6714         addr_t offset_addr;
6715         addr_t address;
6716 
6717         if (add)
6718             offset_addr = Rn + imm32;
6719         else
6720             offset_addr = Rn - imm32;
6721 
6722         // address = if index then offset_addr else R[n];
6723         if (index)
6724             address = offset_addr;
6725         else
6726             address = Rn;
6727 
6728         // data = MemU[address,2];
6729         RegisterInfo base_reg;
6730         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6731 
6732         EmulateInstruction::Context context;
6733         context.type = eContextRegisterLoad;
6734         context.SetRegisterPlusOffset (base_reg, address - Rn);
6735 
6736         uint64_t data = MemURead (context, address, 2, 0, &success);
6737         if (!success)
6738             return false;
6739 
6740         // if wback then R[n] = offset_addr;
6741         if (wback)
6742         {
6743             context.type = eContextAdjustBaseRegister;
6744             context.SetAddress (offset_addr);
6745             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6746                 return false;
6747         }
6748 
6749         // if UnalignedSupport() || address<0> = '0' then
6750         if (UnalignedSupport () || BitIsClear (address, 0))
6751         {
6752             // R[t] = ZeroExtend(data, 32);
6753             context.type = eContextRegisterLoad;
6754             context.SetRegisterPlusOffset (base_reg, address - Rn);
6755             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6756                 return false;
6757         }
6758         else // Can only apply before ARMv7
6759         {
6760             // R[t] = bits(32) UNKNOWN;
6761             WriteBits32Unknown (t);
6762         }
6763     }
6764     return true;
6765 }
6766 
6767 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6768 // zero-extends it to form a 32-bit word, and writes it to a register.
6769 bool
6770 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6771 {
6772 #if 0
6773     if ConditionPassed() then
6774         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6775         base = Align(PC,4);
6776         address = if add then (base + imm32) else (base - imm32);
6777         data = MemU[address,2];
6778         if UnalignedSupport() || address<0> = '0' then
6779             R[t] = ZeroExtend(data, 32);
6780         else // Can only apply before ARMv7
6781             R[t] = bits(32) UNKNOWN;
6782 #endif
6783 
6784     bool success = false;
6785 
6786     if (ConditionPassed(opcode))
6787     {
6788         uint32_t t;
6789         uint32_t imm32;
6790         bool add;
6791 
6792         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6793         switch (encoding)
6794         {
6795             case eEncodingT1:
6796                 // if Rt == '1111' then SEE "Unallocated memory hints";
6797                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6798                 t = Bits32 (opcode, 15, 12);
6799                 imm32 = Bits32 (opcode, 11, 0);
6800                 add = BitIsSet (opcode, 23);
6801 
6802                 // if t == 13 then UNPREDICTABLE;
6803                 if (t == 13)
6804                     return false;
6805 
6806                 break;
6807 
6808             case eEncodingA1:
6809             {
6810                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6811                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6812 
6813                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6814                 t = Bits32 (opcode, 15, 12);
6815                 imm32 = (imm4H << 4) | imm4L;
6816                 add = BitIsSet (opcode, 23);
6817 
6818                 // if t == 15 then UNPREDICTABLE;
6819                 if (t == 15)
6820                     return false;
6821                 break;
6822             }
6823 
6824             default:
6825                 return false;
6826         }
6827 
6828         // base = Align(PC,4);
6829         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6830         if (!success)
6831             return false;
6832 
6833         addr_t base = AlignPC (pc_value);
6834         addr_t address;
6835 
6836         // address = if add then (base + imm32) else (base - imm32);
6837         if (add)
6838             address = base + imm32;
6839         else
6840             address = base - imm32;
6841 
6842         // data = MemU[address,2];
6843         RegisterInfo base_reg;
6844         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6845 
6846         EmulateInstruction::Context context;
6847         context.type = eContextRegisterLoad;
6848         context.SetRegisterPlusOffset (base_reg, address - base);
6849 
6850         uint64_t data = MemURead (context, address, 2, 0, &success);
6851         if (!success)
6852             return false;
6853 
6854 
6855         // if UnalignedSupport() || address<0> = '0' then
6856         if (UnalignedSupport () || BitIsClear (address, 0))
6857         {
6858             // R[t] = ZeroExtend(data, 32);
6859             context.type = eContextRegisterLoad;
6860             context.SetRegisterPlusOffset (base_reg, address - base);
6861             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6862                 return false;
6863 
6864         }
6865         else // Can only apply before ARMv7
6866         {
6867             // R[t] = bits(32) UNKNOWN;
6868             WriteBits32Unknown (t);
6869         }
6870     }
6871     return true;
6872 }
6873 
6874 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6875 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6876 // be shifted left by 0, 1, 2, or 3 bits.
6877 bool
6878 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6879 {
6880 #if 0
6881     if ConditionPassed() then
6882         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6883         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6884         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6885         address = if index then offset_addr else R[n];
6886         data = MemU[address,2];
6887         if wback then R[n] = offset_addr;
6888         if UnalignedSupport() || address<0> = '0' then
6889             R[t] = ZeroExtend(data, 32);
6890         else // Can only apply before ARMv7
6891             R[t] = bits(32) UNKNOWN;
6892 #endif
6893 
6894     bool success = false;
6895 
6896     if (ConditionPassed(opcode))
6897     {
6898         uint32_t t;
6899         uint32_t n;
6900         uint32_t m;
6901         bool index;
6902         bool add;
6903         bool wback;
6904         ARM_ShifterType shift_t;
6905         uint32_t shift_n;
6906 
6907         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6908         switch (encoding)
6909         {
6910             case eEncodingT1:
6911                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6912                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6913                 t = Bits32 (opcode, 2, 0);
6914                 n = Bits32 (opcode, 5, 3);
6915                 m = Bits32 (opcode, 8, 6);
6916 
6917                 // index = TRUE; add = TRUE; wback = FALSE;
6918                 index = true;
6919                 add = true;
6920                 wback = false;
6921 
6922                 // (shift_t, shift_n) = (SRType_LSL, 0);
6923                 shift_t = SRType_LSL;
6924                 shift_n = 0;
6925 
6926                 break;
6927 
6928             case eEncodingT2:
6929                 // if Rn == '1111' then SEE LDRH (literal);
6930                 // if Rt == '1111' then SEE "Unallocated memory hints";
6931                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6932                 t = Bits32 (opcode, 15, 12);
6933                 n = Bits32 (opcode, 19, 16);
6934                 m = Bits32 (opcode, 3, 0);
6935 
6936                 // index = TRUE; add = TRUE; wback = FALSE;
6937                 index = true;
6938                 add = true;
6939                 wback = false;
6940 
6941                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6942                 shift_t = SRType_LSL;
6943                 shift_n = Bits32 (opcode, 5, 4);
6944 
6945                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6946                 if ((t == 13) || BadReg (m))
6947                     return false;
6948                 break;
6949 
6950             case eEncodingA1:
6951                 // if P == '0' && W == '1' then SEE LDRHT;
6952                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6953                 t = Bits32 (opcode, 15, 12);
6954                 n = Bits32 (opcode, 19, 16);
6955                 m = Bits32 (opcode, 3, 0);
6956 
6957                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6958                 index = BitIsSet (opcode, 24);
6959                 add = BitIsSet (opcode, 23);
6960                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6961 
6962                 // (shift_t, shift_n) = (SRType_LSL, 0);
6963                 shift_t = SRType_LSL;
6964                 shift_n = 0;
6965 
6966                 // if t == 15 || m == 15 then UNPREDICTABLE;
6967                 if ((t == 15) || (m == 15))
6968                     return false;
6969 
6970                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6971                 if (wback && ((n == 15) || (n == t)))
6972                     return false;
6973 
6974                 break;
6975 
6976             default:
6977                 return false;
6978         }
6979 
6980         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6981 
6982         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6983         if (!success)
6984             return false;
6985 
6986         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6987         if (!success)
6988             return false;
6989 
6990         addr_t offset_addr;
6991         addr_t address;
6992 
6993         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6994         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6995         if (!success)
6996             return false;
6997 
6998         if (add)
6999             offset_addr = Rn + offset;
7000         else
7001             offset_addr = Rn - offset;
7002 
7003         // address = if index then offset_addr else R[n];
7004         if (index)
7005             address = offset_addr;
7006         else
7007             address = Rn;
7008 
7009         // data = MemU[address,2];
7010         RegisterInfo base_reg;
7011         RegisterInfo offset_reg;
7012         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7013         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7014 
7015         EmulateInstruction::Context context;
7016         context.type = eContextRegisterLoad;
7017         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7018         uint64_t data = MemURead (context, address, 2, 0, &success);
7019         if (!success)
7020             return false;
7021 
7022         // if wback then R[n] = offset_addr;
7023         if (wback)
7024         {
7025             context.type = eContextAdjustBaseRegister;
7026             context.SetAddress (offset_addr);
7027             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7028                 return false;
7029         }
7030 
7031         // if UnalignedSupport() || address<0> = '0' then
7032         if (UnalignedSupport() || BitIsClear (address, 0))
7033         {
7034             // R[t] = ZeroExtend(data, 32);
7035             context.type = eContextRegisterLoad;
7036             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7037             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
7038                 return false;
7039         }
7040         else // Can only apply before ARMv7
7041         {
7042             // R[t] = bits(32) UNKNOWN;
7043             WriteBits32Unknown (t);
7044         }
7045     }
7046     return true;
7047 }
7048 
7049 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
7050 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
7051 // or pre-indexed addressing.
7052 bool
7053 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
7054 {
7055 #if 0
7056     if ConditionPassed() then
7057         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7058         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7059         address = if index then offset_addr else R[n];
7060         R[t] = SignExtend(MemU[address,1], 32);
7061         if wback then R[n] = offset_addr;
7062 #endif
7063 
7064     bool success = false;
7065 
7066     if (ConditionPassed(opcode))
7067     {
7068         uint32_t t;
7069         uint32_t n;
7070         uint32_t imm32;
7071         bool index;
7072         bool add;
7073         bool wback;
7074 
7075         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7076         switch (encoding)
7077         {
7078             case eEncodingT1:
7079                 // if Rt == '1111' then SEE PLI;
7080                 // if Rn == '1111' then SEE LDRSB (literal);
7081                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7082                 t = Bits32 (opcode, 15, 12);
7083                 n = Bits32 (opcode, 19, 16);
7084                 imm32 = Bits32 (opcode, 11, 0);
7085 
7086                 // index = TRUE; add = TRUE; wback = FALSE;
7087                 index = true;
7088                 add = true;
7089                 wback = false;
7090 
7091                 // if t == 13 then UNPREDICTABLE;
7092                 if (t == 13)
7093                     return false;
7094 
7095                 break;
7096 
7097             case eEncodingT2:
7098                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7099                 // if Rn == '1111' then SEE LDRSB (literal);
7100                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7101                 // if P == '0' && W == '0' then UNDEFINED;
7102                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7103                     return false;
7104 
7105                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7106                 t = Bits32 (opcode, 15, 12);
7107                 n = Bits32 (opcode, 19, 16);
7108                 imm32 = Bits32 (opcode, 7, 0);
7109 
7110                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7111                 index = BitIsSet (opcode, 10);
7112                 add = BitIsSet (opcode, 9);
7113                 wback = BitIsSet (opcode, 8);
7114 
7115                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7116                   if (((t == 13) || ((t == 15)
7117                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7118                       || (wback && (n == t)))
7119                     return false;
7120 
7121                 break;
7122 
7123             case eEncodingA1:
7124             {
7125                 // if Rn == '1111' then SEE LDRSB (literal);
7126                 // if P == '0' && W == '1' then SEE LDRSBT;
7127                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7128                 t = Bits32 (opcode, 15, 12);
7129                 n = Bits32 (opcode, 19, 16);
7130 
7131                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7132                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7133                 imm32 = (imm4H << 4) | imm4L;
7134 
7135                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7136                 index = BitIsSet (opcode, 24);
7137                 add = BitIsSet (opcode, 23);
7138                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7139 
7140                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7141                 if ((t == 15) || (wback && (n == t)))
7142                     return false;
7143 
7144                 break;
7145             }
7146 
7147             default:
7148                 return false;
7149         }
7150 
7151         uint64_t Rn = ReadCoreReg (n, &success);
7152         if (!success)
7153             return false;
7154 
7155         addr_t offset_addr;
7156         addr_t address;
7157 
7158         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7159         if (add)
7160             offset_addr = Rn + imm32;
7161         else
7162             offset_addr = Rn - imm32;
7163 
7164         // address = if index then offset_addr else R[n];
7165         if (index)
7166             address = offset_addr;
7167         else
7168             address = Rn;
7169 
7170         // R[t] = SignExtend(MemU[address,1], 32);
7171         RegisterInfo base_reg;
7172         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7173 
7174         EmulateInstruction::Context context;
7175         context.type = eContextRegisterLoad;
7176         context.SetRegisterPlusOffset (base_reg, address - Rn);
7177 
7178         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7179         if (!success)
7180             return false;
7181 
7182         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7183         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7184             return false;
7185 
7186         // if wback then R[n] = offset_addr;
7187         if (wback)
7188         {
7189             context.type = eContextAdjustBaseRegister;
7190             context.SetAddress (offset_addr);
7191             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7192                 return false;
7193         }
7194     }
7195 
7196     return true;
7197 }
7198 
7199 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7200 // sign-extends it to form a 32-bit word, and writes tit to a register.
7201 bool
7202 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7203 {
7204 #if 0
7205     if ConditionPassed() then
7206         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7207         base = Align(PC,4);
7208         address = if add then (base + imm32) else (base - imm32);
7209         R[t] = SignExtend(MemU[address,1], 32);
7210 #endif
7211 
7212     bool success = false;
7213 
7214     if (ConditionPassed(opcode))
7215     {
7216         uint32_t t;
7217         uint32_t imm32;
7218         bool add;
7219 
7220         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7221         switch (encoding)
7222         {
7223             case eEncodingT1:
7224                 // if Rt == '1111' then SEE PLI;
7225                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7226                 t = Bits32 (opcode, 15, 12);
7227                 imm32 = Bits32 (opcode, 11, 0);
7228                 add = BitIsSet (opcode, 23);
7229 
7230                 // if t == 13 then UNPREDICTABLE;
7231                 if (t == 13)
7232                     return false;
7233 
7234                 break;
7235 
7236             case eEncodingA1:
7237             {
7238                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7239                 t = Bits32 (opcode, 15, 12);
7240                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7241                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7242                 imm32 = (imm4H << 4) | imm4L;
7243                 add = BitIsSet (opcode, 23);
7244 
7245                 // if t == 15 then UNPREDICTABLE;
7246                 if (t == 15)
7247                     return false;
7248 
7249                 break;
7250             }
7251 
7252             default:
7253                 return false;
7254         }
7255 
7256         // base = Align(PC,4);
7257         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7258         if (!success)
7259             return false;
7260         uint64_t base = AlignPC (pc_value);
7261 
7262         // address = if add then (base + imm32) else (base - imm32);
7263         addr_t address;
7264         if (add)
7265             address = base + imm32;
7266         else
7267             address = base - imm32;
7268 
7269         // R[t] = SignExtend(MemU[address,1], 32);
7270         RegisterInfo base_reg;
7271         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7272 
7273         EmulateInstruction::Context context;
7274         context.type = eContextRegisterLoad;
7275         context.SetRegisterPlusOffset (base_reg, address - base);
7276 
7277         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7278         if (!success)
7279             return false;
7280 
7281         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7282         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7283             return false;
7284     }
7285     return true;
7286 }
7287 
7288 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7289 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7290 // shifted left by 0, 1, 2, or 3 bits.
7291 bool
7292 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7293 {
7294 #if 0
7295     if ConditionPassed() then
7296         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7297         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7298         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7299         address = if index then offset_addr else R[n];
7300         R[t] = SignExtend(MemU[address,1], 32);
7301         if wback then R[n] = offset_addr;
7302 #endif
7303 
7304     bool success = false;
7305 
7306     if (ConditionPassed(opcode))
7307     {
7308         uint32_t t;
7309         uint32_t n;
7310         uint32_t m;
7311         bool index;
7312         bool add;
7313         bool wback;
7314         ARM_ShifterType shift_t;
7315         uint32_t shift_n;
7316 
7317         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7318         switch (encoding)
7319         {
7320             case eEncodingT1:
7321                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7322                 t = Bits32 (opcode, 2, 0);
7323                 n = Bits32 (opcode, 5, 3);
7324                 m = Bits32 (opcode, 8, 6);
7325 
7326                 // index = TRUE; add = TRUE; wback = FALSE;
7327                 index = true;
7328                 add = true;
7329                 wback = false;
7330 
7331                 // (shift_t, shift_n) = (SRType_LSL, 0);
7332                 shift_t = SRType_LSL;
7333                 shift_n = 0;
7334 
7335                 break;
7336 
7337             case eEncodingT2:
7338                 // if Rt == '1111' then SEE PLI;
7339                 // if Rn == '1111' then SEE LDRSB (literal);
7340                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7341                 t = Bits32 (opcode, 15, 12);
7342                 n = Bits32 (opcode, 19, 16);
7343                 m = Bits32 (opcode, 3, 0);
7344 
7345                 // index = TRUE; add = TRUE; wback = FALSE;
7346                 index = true;
7347                 add = true;
7348                 wback = false;
7349 
7350                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7351                 shift_t = SRType_LSL;
7352                 shift_n = Bits32 (opcode, 5, 4);
7353 
7354                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7355                 if ((t == 13) || BadReg (m))
7356                     return false;
7357                 break;
7358 
7359             case eEncodingA1:
7360                 // if P == '0' && W == '1' then SEE LDRSBT;
7361                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7362                 t = Bits32 (opcode, 15, 12);
7363                 n = Bits32 (opcode, 19, 16);
7364                 m = Bits32 (opcode, 3, 0);
7365 
7366                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7367                 index = BitIsSet (opcode, 24);
7368                 add = BitIsSet (opcode, 23);
7369                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7370 
7371                 // (shift_t, shift_n) = (SRType_LSL, 0);
7372                 shift_t = SRType_LSL;
7373                 shift_n = 0;
7374 
7375                 // if t == 15 || m == 15 then UNPREDICTABLE;
7376                 if ((t == 15) || (m == 15))
7377                     return false;
7378 
7379                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7380                 if (wback && ((n == 15) || (n == t)))
7381                     return false;
7382                 break;
7383 
7384             default:
7385                 return false;
7386         }
7387 
7388         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7389         if (!success)
7390             return false;
7391 
7392         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7393         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7394         if (!success)
7395             return false;
7396 
7397         addr_t offset_addr;
7398         addr_t address;
7399 
7400         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7401         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7402         if (!success)
7403             return false;
7404 
7405         if (add)
7406             offset_addr = Rn + offset;
7407         else
7408             offset_addr = Rn - offset;
7409 
7410         // address = if index then offset_addr else R[n];
7411         if (index)
7412             address = offset_addr;
7413         else
7414             address = Rn;
7415 
7416         // R[t] = SignExtend(MemU[address,1], 32);
7417         RegisterInfo base_reg;
7418         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7419         RegisterInfo offset_reg;
7420         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7421 
7422         EmulateInstruction::Context context;
7423         context.type = eContextRegisterLoad;
7424         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7425 
7426         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7427         if (!success)
7428             return false;
7429 
7430         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7431         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7432             return false;
7433 
7434         // if wback then R[n] = offset_addr;
7435         if (wback)
7436         {
7437             context.type = eContextAdjustBaseRegister;
7438             context.SetAddress (offset_addr);
7439             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7440                 return false;
7441         }
7442     }
7443     return true;
7444 }
7445 
7446 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7447 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7448 // pre-indexed addressing.
7449 bool
7450 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7451 {
7452 #if 0
7453     if ConditionPassed() then
7454         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7455         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7456         address = if index then offset_addr else R[n];
7457         data = MemU[address,2];
7458         if wback then R[n] = offset_addr;
7459         if UnalignedSupport() || address<0> = '0' then
7460             R[t] = SignExtend(data, 32);
7461         else // Can only apply before ARMv7
7462             R[t] = bits(32) UNKNOWN;
7463 #endif
7464 
7465     bool success = false;
7466 
7467     if (ConditionPassed(opcode))
7468     {
7469         uint32_t t;
7470         uint32_t n;
7471         uint32_t imm32;
7472         bool index;
7473         bool add;
7474         bool wback;
7475 
7476         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7477         switch (encoding)
7478         {
7479             case eEncodingT1:
7480                 // if Rn == '1111' then SEE LDRSH (literal);
7481                 // if Rt == '1111' then SEE "Unallocated memory hints";
7482                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7483                 t = Bits32 (opcode, 15, 12);
7484                 n = Bits32 (opcode, 19, 16);
7485                 imm32 = Bits32 (opcode, 11, 0);
7486 
7487                 // index = TRUE; add = TRUE; wback = FALSE;
7488                 index = true;
7489                 add = true;
7490                 wback = false;
7491 
7492                 // if t == 13 then UNPREDICTABLE;
7493                 if (t == 13)
7494                     return false;
7495 
7496                 break;
7497 
7498             case eEncodingT2:
7499                 // if Rn == '1111' then SEE LDRSH (literal);
7500                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7501                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7502                 // if P == '0' && W == '0' then UNDEFINED;
7503                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7504                   return false;
7505 
7506                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7507                 t = Bits32 (opcode, 15, 12);
7508                 n = Bits32 (opcode, 19, 16);
7509                 imm32 = Bits32 (opcode, 7, 0);
7510 
7511                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7512                 index = BitIsSet (opcode, 10);
7513                 add = BitIsSet (opcode, 9);
7514                 wback = BitIsSet (opcode, 8);
7515 
7516                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7517                 if (BadReg (t) || (wback && (n == t)))
7518                     return false;
7519 
7520                 break;
7521 
7522             case eEncodingA1:
7523             {
7524                 // if Rn == '1111' then SEE LDRSH (literal);
7525                 // if P == '0' && W == '1' then SEE LDRSHT;
7526                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7527                 t = Bits32 (opcode, 15, 12);
7528                 n = Bits32 (opcode, 19, 16);
7529                 uint32_t imm4H = Bits32 (opcode, 11,8);
7530                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7531                 imm32 = (imm4H << 4) | imm4L;
7532 
7533                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7534                 index = BitIsSet (opcode, 24);
7535                 add = BitIsSet (opcode, 23);
7536                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7537 
7538                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7539                 if ((t == 15) || (wback && (n == t)))
7540                     return false;
7541 
7542                 break;
7543             }
7544 
7545             default:
7546                 return false;
7547         }
7548 
7549         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7550         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7551         if (!success)
7552             return false;
7553 
7554         addr_t offset_addr;
7555         if (add)
7556             offset_addr = Rn + imm32;
7557         else
7558             offset_addr = Rn - imm32;
7559 
7560         // address = if index then offset_addr else R[n];
7561         addr_t address;
7562         if (index)
7563             address = offset_addr;
7564         else
7565             address = Rn;
7566 
7567         // data = MemU[address,2];
7568         RegisterInfo base_reg;
7569         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7570 
7571         EmulateInstruction::Context context;
7572         context.type = eContextRegisterLoad;
7573         context.SetRegisterPlusOffset (base_reg, address - Rn);
7574 
7575         uint64_t data = MemURead (context, address, 2, 0, &success);
7576         if (!success)
7577             return false;
7578 
7579         // if wback then R[n] = offset_addr;
7580         if (wback)
7581         {
7582             context.type = eContextAdjustBaseRegister;
7583             context.SetAddress (offset_addr);
7584             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7585                 return false;
7586         }
7587 
7588         // if UnalignedSupport() || address<0> = '0' then
7589         if (UnalignedSupport() || BitIsClear (address, 0))
7590         {
7591             // R[t] = SignExtend(data, 32);
7592             int64_t signed_data = llvm::SignExtend64<16>(data);
7593             context.type = eContextRegisterLoad;
7594             context.SetRegisterPlusOffset (base_reg, address - Rn);
7595             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7596                 return false;
7597         }
7598         else // Can only apply before ARMv7
7599         {
7600             // R[t] = bits(32) UNKNOWN;
7601             WriteBits32Unknown (t);
7602         }
7603     }
7604     return true;
7605 }
7606 
7607 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7608 // sign-extends it to from a 32-bit word, and writes it to a register.
7609 bool
7610 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7611 {
7612 #if 0
7613     if ConditionPassed() then
7614         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7615         base = Align(PC,4);
7616         address = if add then (base + imm32) else (base - imm32);
7617         data = MemU[address,2];
7618         if UnalignedSupport() || address<0> = '0' then
7619             R[t] = SignExtend(data, 32);
7620         else // Can only apply before ARMv7
7621             R[t] = bits(32) UNKNOWN;
7622 #endif
7623 
7624     bool success = false;
7625 
7626     if (ConditionPassed(opcode))
7627     {
7628         uint32_t t;
7629         uint32_t imm32;
7630         bool add;
7631 
7632         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7633         switch (encoding)
7634         {
7635             case eEncodingT1:
7636                 // if Rt == '1111' then SEE "Unallocated memory hints";
7637                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7638                 t = Bits32  (opcode, 15, 12);
7639                 imm32 = Bits32 (opcode, 11, 0);
7640                 add = BitIsSet (opcode, 23);
7641 
7642                 // if t == 13 then UNPREDICTABLE;
7643                 if (t == 13)
7644                     return false;
7645 
7646                 break;
7647 
7648             case eEncodingA1:
7649             {
7650                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7651                 t = Bits32 (opcode, 15, 12);
7652                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7653                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7654                 imm32 = (imm4H << 4) | imm4L;
7655                 add = BitIsSet (opcode, 23);
7656 
7657                 // if t == 15 then UNPREDICTABLE;
7658                 if (t == 15)
7659                     return false;
7660 
7661                 break;
7662             }
7663             default:
7664                 return false;
7665         }
7666 
7667         // base = Align(PC,4);
7668         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7669         if (!success)
7670             return false;
7671 
7672         uint64_t base = AlignPC (pc_value);
7673 
7674         addr_t address;
7675         // address = if add then (base + imm32) else (base - imm32);
7676         if (add)
7677             address = base + imm32;
7678         else
7679             address = base - imm32;
7680 
7681         // data = MemU[address,2];
7682         RegisterInfo base_reg;
7683         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7684 
7685         EmulateInstruction::Context context;
7686         context.type = eContextRegisterLoad;
7687         context.SetRegisterPlusOffset (base_reg, imm32);
7688 
7689         uint64_t data = MemURead (context, address, 2, 0, &success);
7690         if (!success)
7691             return false;
7692 
7693         // if UnalignedSupport() || address<0> = '0' then
7694         if (UnalignedSupport() || BitIsClear (address, 0))
7695         {
7696             // R[t] = SignExtend(data, 32);
7697             int64_t signed_data = llvm::SignExtend64<16>(data);
7698             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7699                 return false;
7700         }
7701         else // Can only apply before ARMv7
7702         {
7703             // R[t] = bits(32) UNKNOWN;
7704             WriteBits32Unknown (t);
7705         }
7706     }
7707     return true;
7708 }
7709 
7710 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7711 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7712 // shifted left by 0, 1, 2, or 3 bits.
7713 bool
7714 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7715 {
7716 #if 0
7717     if ConditionPassed() then
7718         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7719         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7720         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7721         address = if index then offset_addr else R[n];
7722         data = MemU[address,2];
7723         if wback then R[n] = offset_addr;
7724         if UnalignedSupport() || address<0> = '0' then
7725             R[t] = SignExtend(data, 32);
7726         else // Can only apply before ARMv7
7727             R[t] = bits(32) UNKNOWN;
7728 #endif
7729 
7730     bool success = false;
7731 
7732     if (ConditionPassed(opcode))
7733     {
7734         uint32_t t;
7735         uint32_t n;
7736         uint32_t m;
7737         bool index;
7738         bool add;
7739         bool wback;
7740         ARM_ShifterType shift_t;
7741         uint32_t shift_n;
7742 
7743         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7744         switch (encoding)
7745         {
7746             case eEncodingT1:
7747                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7748                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7749                 t = Bits32 (opcode, 2, 0);
7750                 n = Bits32 (opcode, 5, 3);
7751                 m = Bits32 (opcode, 8, 6);
7752 
7753                 // index = TRUE; add = TRUE; wback = FALSE;
7754                 index = true;
7755                 add = true;
7756                 wback = false;
7757 
7758                 // (shift_t, shift_n) = (SRType_LSL, 0);
7759                 shift_t = SRType_LSL;
7760                 shift_n = 0;
7761 
7762                 break;
7763 
7764             case eEncodingT2:
7765                 // if Rn == '1111' then SEE LDRSH (literal);
7766                 // if Rt == '1111' then SEE "Unallocated memory hints";
7767                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7768                 t = Bits32 (opcode, 15, 12);
7769                 n = Bits32 (opcode, 19, 16);
7770                 m = Bits32 (opcode, 3, 0);
7771 
7772                 // index = TRUE; add = TRUE; wback = FALSE;
7773                 index = true;
7774                 add = true;
7775                 wback = false;
7776 
7777                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7778                 shift_t = SRType_LSL;
7779                 shift_n = Bits32 (opcode, 5, 4);
7780 
7781                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7782                 if ((t == 13) || BadReg (m))
7783                     return false;
7784 
7785                 break;
7786 
7787             case eEncodingA1:
7788                 // if P == '0' && W == '1' then SEE LDRSHT;
7789                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7790                 t = Bits32 (opcode, 15, 12);
7791                 n = Bits32 (opcode, 19, 16);
7792                 m = Bits32 (opcode, 3, 0);
7793 
7794                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7795                 index = BitIsSet (opcode, 24);
7796                 add = BitIsSet (opcode, 23);
7797                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7798 
7799                 // (shift_t, shift_n) = (SRType_LSL, 0);
7800                 shift_t = SRType_LSL;
7801                 shift_n = 0;
7802 
7803                 // if t == 15 || m == 15 then UNPREDICTABLE;
7804                 if ((t == 15) || (m == 15))
7805                     return false;
7806 
7807                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7808                 if (wback && ((n == 15) || (n == t)))
7809                     return false;
7810 
7811                 break;
7812 
7813             default:
7814                 return false;
7815         }
7816 
7817         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7818         if (!success)
7819             return false;
7820 
7821         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7822         if (!success)
7823             return false;
7824 
7825         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7826         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7827         if (!success)
7828             return false;
7829 
7830         addr_t offset_addr;
7831         addr_t address;
7832 
7833         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7834         if (add)
7835             offset_addr = Rn + offset;
7836         else
7837             offset_addr = Rn - offset;
7838 
7839         // address = if index then offset_addr else R[n];
7840         if (index)
7841             address = offset_addr;
7842         else
7843             address = Rn;
7844 
7845         // data = MemU[address,2];
7846         RegisterInfo base_reg;
7847         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7848 
7849         RegisterInfo offset_reg;
7850         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7851 
7852         EmulateInstruction::Context context;
7853         context.type = eContextRegisterLoad;
7854         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7855 
7856         uint64_t data = MemURead (context, address, 2, 0, &success);
7857         if (!success)
7858             return false;
7859 
7860         // if wback then R[n] = offset_addr;
7861         if (wback)
7862         {
7863             context.type = eContextAdjustBaseRegister;
7864             context.SetAddress (offset_addr);
7865             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7866                 return false;
7867         }
7868 
7869         // if UnalignedSupport() || address<0> = '0' then
7870         if (UnalignedSupport() || BitIsClear (address, 0))
7871         {
7872             // R[t] = SignExtend(data, 32);
7873             context.type = eContextRegisterLoad;
7874             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7875 
7876             int64_t signed_data = llvm::SignExtend64<16>(data);
7877             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7878                 return false;
7879         }
7880         else // Can only apply before ARMv7
7881         {
7882             // R[t] = bits(32) UNKNOWN;
7883             WriteBits32Unknown (t);
7884         }
7885     }
7886     return true;
7887 }
7888 
7889 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7890 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7891 bool
7892 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7893 {
7894 #if 0
7895     if ConditionPassed() then
7896         EncodingSpecificOperations();
7897         rotated = ROR(R[m], rotation);
7898         R[d] = SignExtend(rotated<7:0>, 32);
7899 #endif
7900 
7901     bool success = false;
7902 
7903     if (ConditionPassed(opcode))
7904     {
7905         uint32_t d;
7906         uint32_t m;
7907         uint32_t rotation;
7908 
7909         // EncodingSpecificOperations();
7910         switch (encoding)
7911         {
7912             case eEncodingT1:
7913                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7914                 d = Bits32 (opcode, 2, 0);
7915                 m = Bits32 (opcode, 5, 3);
7916                 rotation = 0;
7917 
7918                 break;
7919 
7920             case eEncodingT2:
7921                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7922                 d = Bits32 (opcode, 11, 8);
7923                 m = Bits32 (opcode, 3, 0);
7924                 rotation = Bits32 (opcode, 5, 4) << 3;
7925 
7926                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7927                 if (BadReg (d) || BadReg (m))
7928                     return false;
7929 
7930                 break;
7931 
7932             case eEncodingA1:
7933                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7934                 d = Bits32 (opcode, 15, 12);
7935                 m = Bits32 (opcode, 3, 0);
7936                 rotation = Bits32 (opcode, 11, 10) << 3;
7937 
7938                 // if d == 15 || m == 15 then UNPREDICTABLE;
7939                 if ((d == 15) || (m == 15))
7940                     return false;
7941 
7942                 break;
7943 
7944             default:
7945                 return false;
7946         }
7947 
7948         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7949         if (!success)
7950             return false;
7951 
7952         // rotated = ROR(R[m], rotation);
7953         uint64_t rotated = ROR (Rm, rotation, &success);
7954         if (!success)
7955             return false;
7956 
7957         // R[d] = SignExtend(rotated<7:0>, 32);
7958         int64_t data = llvm::SignExtend64<8>(rotated);
7959 
7960         RegisterInfo source_reg;
7961         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7962 
7963         EmulateInstruction::Context context;
7964         context.type = eContextRegisterLoad;
7965         context.SetRegister (source_reg);
7966 
7967         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7968             return false;
7969     }
7970     return true;
7971 }
7972 
7973 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7974 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7975 bool
7976 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7977 {
7978 #if 0
7979     if ConditionPassed() then
7980         EncodingSpecificOperations();
7981         rotated = ROR(R[m], rotation);
7982         R[d] = SignExtend(rotated<15:0>, 32);
7983 #endif
7984 
7985     bool success = false;
7986 
7987     if (ConditionPassed(opcode))
7988     {
7989         uint32_t d;
7990         uint32_t m;
7991         uint32_t rotation;
7992 
7993         // EncodingSpecificOperations();
7994         switch (encoding)
7995         {
7996             case eEncodingT1:
7997                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7998                 d = Bits32 (opcode, 2, 0);
7999                 m = Bits32 (opcode, 5, 3);
8000                 rotation = 0;
8001 
8002                 break;
8003 
8004             case eEncodingT2:
8005                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8006                 d = Bits32 (opcode, 11, 8);
8007                 m = Bits32 (opcode, 3, 0);
8008                 rotation = Bits32 (opcode, 5, 4) << 3;
8009 
8010                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8011                 if (BadReg (d) || BadReg (m))
8012                     return false;
8013 
8014                 break;
8015 
8016             case eEncodingA1:
8017                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8018                 d = Bits32 (opcode, 15, 12);
8019                 m = Bits32 (opcode, 3, 0);
8020                 rotation = Bits32 (opcode, 11, 10) << 3;
8021 
8022                 // if d == 15 || m == 15 then UNPREDICTABLE;
8023                 if ((d == 15) || (m == 15))
8024                     return false;
8025 
8026                 break;
8027 
8028             default:
8029                 return false;
8030         }
8031 
8032         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8033         if (!success)
8034             return false;
8035 
8036         // rotated = ROR(R[m], rotation);
8037         uint64_t rotated = ROR (Rm, rotation, &success);
8038         if (!success)
8039             return false;
8040 
8041         // R[d] = SignExtend(rotated<15:0>, 32);
8042         RegisterInfo source_reg;
8043         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8044 
8045         EmulateInstruction::Context context;
8046         context.type = eContextRegisterLoad;
8047         context.SetRegister (source_reg);
8048 
8049         int64_t data = llvm::SignExtend64<16> (rotated);
8050         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
8051             return false;
8052     }
8053 
8054     return true;
8055 }
8056 
8057 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
8058 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
8059 bool
8060 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
8061 {
8062 #if 0
8063     if ConditionPassed() then
8064         EncodingSpecificOperations();
8065         rotated = ROR(R[m], rotation);
8066         R[d] = ZeroExtend(rotated<7:0>, 32);
8067 #endif
8068 
8069     bool success = false;
8070 
8071     if (ConditionPassed(opcode))
8072     {
8073         uint32_t d;
8074         uint32_t m;
8075         uint32_t rotation;
8076 
8077         // EncodingSpecificOperations();
8078         switch (encoding)
8079         {
8080             case eEncodingT1:
8081                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8082                 d = Bits32 (opcode, 2, 0);
8083                 m = Bits32 (opcode, 5, 3);
8084                 rotation = 0;
8085 
8086                 break;
8087 
8088             case eEncodingT2:
8089                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8090                 d = Bits32 (opcode, 11, 8);
8091                 m = Bits32 (opcode, 3, 0);
8092                   rotation = Bits32 (opcode, 5, 4) << 3;
8093 
8094                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8095                 if (BadReg (d) || BadReg (m))
8096                   return false;
8097 
8098                 break;
8099 
8100             case eEncodingA1:
8101                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8102                 d = Bits32 (opcode, 15, 12);
8103                 m = Bits32 (opcode, 3, 0);
8104                 rotation = Bits32 (opcode, 11, 10) << 3;
8105 
8106                 // if d == 15 || m == 15 then UNPREDICTABLE;
8107                 if ((d == 15) || (m == 15))
8108                     return false;
8109 
8110                 break;
8111 
8112             default:
8113                 return false;
8114         }
8115 
8116         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8117         if (!success)
8118             return false;
8119 
8120         // rotated = ROR(R[m], rotation);
8121         uint64_t rotated = ROR (Rm, rotation, &success);
8122         if (!success)
8123             return false;
8124 
8125         // R[d] = ZeroExtend(rotated<7:0>, 32);
8126         RegisterInfo source_reg;
8127         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8128 
8129         EmulateInstruction::Context context;
8130         context.type = eContextRegisterLoad;
8131         context.SetRegister (source_reg);
8132 
8133         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8134             return false;
8135     }
8136     return true;
8137 }
8138 
8139 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8140 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8141 bool
8142 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8143 {
8144 #if 0
8145     if ConditionPassed() then
8146         EncodingSpecificOperations();
8147         rotated = ROR(R[m], rotation);
8148         R[d] = ZeroExtend(rotated<15:0>, 32);
8149 #endif
8150 
8151     bool success = false;
8152 
8153     if (ConditionPassed(opcode))
8154     {
8155         uint32_t d;
8156         uint32_t m;
8157         uint32_t rotation;
8158 
8159         switch (encoding)
8160         {
8161             case eEncodingT1:
8162                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8163                 d = Bits32 (opcode, 2, 0);
8164                 m = Bits32 (opcode, 5, 3);
8165                 rotation = 0;
8166 
8167                 break;
8168 
8169             case eEncodingT2:
8170                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8171                 d = Bits32 (opcode, 11, 8);
8172                 m = Bits32 (opcode, 3, 0);
8173                 rotation = Bits32 (opcode, 5, 4) << 3;
8174 
8175                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8176                 if (BadReg (d) || BadReg (m))
8177                   return false;
8178 
8179                 break;
8180 
8181             case eEncodingA1:
8182                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8183                 d = Bits32 (opcode, 15, 12);
8184                 m = Bits32 (opcode, 3, 0);
8185                 rotation = Bits32 (opcode, 11, 10) << 3;
8186 
8187                 // if d == 15 || m == 15 then UNPREDICTABLE;
8188                 if ((d == 15) || (m == 15))
8189                     return false;
8190 
8191                 break;
8192 
8193             default:
8194                 return false;
8195         }
8196 
8197         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8198         if (!success)
8199             return false;
8200 
8201         // rotated = ROR(R[m], rotation);
8202         uint64_t rotated = ROR (Rm, rotation, &success);
8203         if (!success)
8204             return false;
8205 
8206         // R[d] = ZeroExtend(rotated<15:0>, 32);
8207         RegisterInfo source_reg;
8208         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8209 
8210         EmulateInstruction::Context context;
8211         context.type = eContextRegisterLoad;
8212         context.SetRegister (source_reg);
8213 
8214         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8215             return false;
8216     }
8217     return true;
8218 }
8219 
8220 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8221 // word respectively.
8222 bool
8223 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8224 {
8225 #if 0
8226     if ConditionPassed() then
8227         EncodingSpecificOperations();
8228         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8229             UNPREDICTABLE;
8230         else
8231             address = if increment then R[n] else R[n]-8;
8232             if wordhigher then address = address+4;
8233             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8234             BranchWritePC(MemA[address,4]);
8235             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8236 #endif
8237 
8238     bool success = false;
8239 
8240     if (ConditionPassed(opcode))
8241     {
8242         uint32_t n;
8243         bool wback;
8244         bool increment;
8245         bool wordhigher;
8246 
8247         // EncodingSpecificOperations();
8248         switch (encoding)
8249         {
8250             case eEncodingT1:
8251                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8252                 n = Bits32 (opcode, 19, 16);
8253                 wback = BitIsSet (opcode, 21);
8254                 increment = false;
8255                 wordhigher = false;
8256 
8257                 // if n == 15 then UNPREDICTABLE;
8258                 if (n == 15)
8259                     return false;
8260 
8261                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8262                 if (InITBlock() && !LastInITBlock())
8263                     return false;
8264 
8265                 break;
8266 
8267             case eEncodingT2:
8268                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8269                 n = Bits32 (opcode, 19, 16);
8270                 wback = BitIsSet (opcode, 21);
8271                 increment = true;
8272                 wordhigher = false;
8273 
8274                 // if n == 15 then UNPREDICTABLE;
8275                 if (n == 15)
8276                     return false;
8277 
8278                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8279                 if (InITBlock() && !LastInITBlock())
8280                     return false;
8281 
8282                 break;
8283 
8284             case eEncodingA1:
8285                 // n = UInt(Rn);
8286                 n = Bits32 (opcode, 19, 16);
8287 
8288                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8289                 wback = BitIsSet (opcode, 21);
8290                 increment = BitIsSet (opcode, 23);
8291                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8292 
8293                 // if n == 15 then UNPREDICTABLE;
8294                 if (n == 15)
8295                     return false;
8296 
8297                 break;
8298 
8299             default:
8300                 return false;
8301         }
8302 
8303         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8304         if (!CurrentModeIsPrivileged ())
8305             // UNPREDICTABLE;
8306             return false;
8307         else
8308         {
8309             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8310             if (!success)
8311                 return false;
8312 
8313             addr_t address;
8314             // address = if increment then R[n] else R[n]-8;
8315             if (increment)
8316                 address = Rn;
8317             else
8318                 address = Rn - 8;
8319 
8320             // if wordhigher then address = address+4;
8321             if (wordhigher)
8322                 address = address + 4;
8323 
8324             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8325             RegisterInfo base_reg;
8326             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8327 
8328             EmulateInstruction::Context context;
8329             context.type = eContextReturnFromException;
8330             context.SetRegisterPlusOffset (base_reg, address - Rn);
8331 
8332             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8333             if (!success)
8334                 return false;
8335 
8336             CPSRWriteByInstr (data, 15, true);
8337 
8338             // BranchWritePC(MemA[address,4]);
8339             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8340             if (!success)
8341                 return false;
8342 
8343             BranchWritePC (context, data2);
8344 
8345             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8346             if (wback)
8347             {
8348                 context.type = eContextAdjustBaseRegister;
8349                 if (increment)
8350                 {
8351                     context.SetOffset (8);
8352                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8353                         return false;
8354                 }
8355                 else
8356                 {
8357                     context.SetOffset (-8);
8358                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8359                         return false;
8360                 }
8361             } // if wback
8362         }
8363     } // if ConditionPassed()
8364     return true;
8365 }
8366 
8367 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8368 // and writes the result to the destination register.  It can optionally update the condition flags based on
8369 // the result.
8370 bool
8371 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8372 {
8373 #if 0
8374     // ARM pseudo code...
8375     if ConditionPassed() then
8376         EncodingSpecificOperations();
8377         result = R[n] EOR imm32;
8378         if d == 15 then         // Can only occur for ARM encoding
8379             ALUWritePC(result); // setflags is always FALSE here
8380         else
8381             R[d] = result;
8382             if setflags then
8383                 APSR.N = result<31>;
8384                 APSR.Z = IsZeroBit(result);
8385                 APSR.C = carry;
8386                 // APSR.V unchanged
8387 #endif
8388 
8389     bool success = false;
8390 
8391     if (ConditionPassed(opcode))
8392     {
8393         uint32_t Rd, Rn;
8394         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8395         bool setflags;
8396         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8397         switch (encoding)
8398         {
8399         case eEncodingT1:
8400             Rd = Bits32(opcode, 11, 8);
8401             Rn = Bits32(opcode, 19, 16);
8402             setflags = BitIsSet(opcode, 20);
8403             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8404             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8405             if (Rd == 15 && setflags)
8406                 return EmulateTEQImm (opcode, eEncodingT1);
8407             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8408                 return false;
8409             break;
8410         case eEncodingA1:
8411             Rd = Bits32(opcode, 15, 12);
8412             Rn = Bits32(opcode, 19, 16);
8413             setflags = BitIsSet(opcode, 20);
8414             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8415 
8416             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8417             if (Rd == 15 && setflags)
8418                 return EmulateSUBSPcLrEtc (opcode, encoding);
8419             break;
8420         default:
8421             return false;
8422         }
8423 
8424         // Read the first operand.
8425         uint32_t val1 = ReadCoreReg(Rn, &success);
8426         if (!success)
8427             return false;
8428 
8429         uint32_t result = val1 ^ imm32;
8430 
8431         EmulateInstruction::Context context;
8432         context.type = EmulateInstruction::eContextImmediate;
8433         context.SetNoArgs ();
8434 
8435         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8436             return false;
8437     }
8438     return true;
8439 }
8440 
8441 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8442 // optionally-shifted register value, and writes the result to the destination register.
8443 // It can optionally update the condition flags based on the result.
8444 bool
8445 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8446 {
8447 #if 0
8448     // ARM pseudo code...
8449     if ConditionPassed() then
8450         EncodingSpecificOperations();
8451         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8452         result = R[n] EOR shifted;
8453         if d == 15 then         // Can only occur for ARM encoding
8454             ALUWritePC(result); // setflags is always FALSE here
8455         else
8456             R[d] = result;
8457             if setflags then
8458                 APSR.N = result<31>;
8459                 APSR.Z = IsZeroBit(result);
8460                 APSR.C = carry;
8461                 // APSR.V unchanged
8462 #endif
8463 
8464     bool success = false;
8465 
8466     if (ConditionPassed(opcode))
8467     {
8468         uint32_t Rd, Rn, Rm;
8469         ARM_ShifterType shift_t;
8470         uint32_t shift_n; // the shift applied to the value read from Rm
8471         bool setflags;
8472         uint32_t carry;
8473         switch (encoding)
8474         {
8475         case eEncodingT1:
8476             Rd = Rn = Bits32(opcode, 2, 0);
8477             Rm = Bits32(opcode, 5, 3);
8478             setflags = !InITBlock();
8479             shift_t = SRType_LSL;
8480             shift_n = 0;
8481             break;
8482         case eEncodingT2:
8483             Rd = Bits32(opcode, 11, 8);
8484             Rn = Bits32(opcode, 19, 16);
8485             Rm = Bits32(opcode, 3, 0);
8486             setflags = BitIsSet(opcode, 20);
8487             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8488             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8489             if (Rd == 15 && setflags)
8490                 return EmulateTEQReg (opcode, eEncodingT1);
8491             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8492                 return false;
8493             break;
8494         case eEncodingA1:
8495             Rd = Bits32(opcode, 15, 12);
8496             Rn = Bits32(opcode, 19, 16);
8497             Rm = Bits32(opcode, 3, 0);
8498             setflags = BitIsSet(opcode, 20);
8499             shift_n = DecodeImmShiftARM(opcode, shift_t);
8500 
8501             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8502             if (Rd == 15 && setflags)
8503                 return EmulateSUBSPcLrEtc (opcode, encoding);
8504             break;
8505         default:
8506             return false;
8507         }
8508 
8509         // Read the first operand.
8510         uint32_t val1 = ReadCoreReg(Rn, &success);
8511         if (!success)
8512             return false;
8513 
8514         // Read the second operand.
8515         uint32_t val2 = ReadCoreReg(Rm, &success);
8516         if (!success)
8517             return false;
8518 
8519         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8520         if (!success)
8521             return false;
8522         uint32_t result = val1 ^ shifted;
8523 
8524         EmulateInstruction::Context context;
8525         context.type = EmulateInstruction::eContextImmediate;
8526         context.SetNoArgs ();
8527 
8528         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8529             return false;
8530     }
8531     return true;
8532 }
8533 
8534 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8535 // writes the result to the destination register.  It can optionally update the condition flags based
8536 // on the result.
8537 bool
8538 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8539 {
8540 #if 0
8541     // ARM pseudo code...
8542     if ConditionPassed() then
8543         EncodingSpecificOperations();
8544         result = R[n] OR imm32;
8545         if d == 15 then         // Can only occur for ARM encoding
8546             ALUWritePC(result); // setflags is always FALSE here
8547         else
8548             R[d] = result;
8549             if setflags then
8550                 APSR.N = result<31>;
8551                 APSR.Z = IsZeroBit(result);
8552                 APSR.C = carry;
8553                 // APSR.V unchanged
8554 #endif
8555 
8556     bool success = false;
8557 
8558     if (ConditionPassed(opcode))
8559     {
8560         uint32_t Rd, Rn;
8561         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8562         bool setflags;
8563         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8564         switch (encoding)
8565         {
8566         case eEncodingT1:
8567             Rd = Bits32(opcode, 11, 8);
8568             Rn = Bits32(opcode, 19, 16);
8569             setflags = BitIsSet(opcode, 20);
8570             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8571             // if Rn == '1111' then SEE MOV (immediate);
8572             if (Rn == 15)
8573                 return EmulateMOVRdImm (opcode, eEncodingT2);
8574             if (BadReg(Rd) || Rn == 13)
8575                 return false;
8576             break;
8577         case eEncodingA1:
8578             Rd = Bits32(opcode, 15, 12);
8579             Rn = Bits32(opcode, 19, 16);
8580             setflags = BitIsSet(opcode, 20);
8581             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8582 
8583             if (Rd == 15 && setflags)
8584                 return EmulateSUBSPcLrEtc (opcode, encoding);
8585             break;
8586         default:
8587             return false;
8588         }
8589 
8590         // Read the first operand.
8591         uint32_t val1 = ReadCoreReg(Rn, &success);
8592         if (!success)
8593             return false;
8594 
8595         uint32_t result = val1 | imm32;
8596 
8597         EmulateInstruction::Context context;
8598         context.type = EmulateInstruction::eContextImmediate;
8599         context.SetNoArgs ();
8600 
8601         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8602             return false;
8603     }
8604     return true;
8605 }
8606 
8607 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8608 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8609 // on the result.
8610 bool
8611 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8612 {
8613 #if 0
8614     // ARM pseudo code...
8615     if ConditionPassed() then
8616         EncodingSpecificOperations();
8617         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8618         result = R[n] OR shifted;
8619         if d == 15 then         // Can only occur for ARM encoding
8620             ALUWritePC(result); // setflags is always FALSE here
8621         else
8622             R[d] = result;
8623             if setflags then
8624                 APSR.N = result<31>;
8625                 APSR.Z = IsZeroBit(result);
8626                 APSR.C = carry;
8627                 // APSR.V unchanged
8628 #endif
8629 
8630     bool success = false;
8631 
8632     if (ConditionPassed(opcode))
8633     {
8634         uint32_t Rd, Rn, Rm;
8635         ARM_ShifterType shift_t;
8636         uint32_t shift_n; // the shift applied to the value read from Rm
8637         bool setflags;
8638         uint32_t carry;
8639         switch (encoding)
8640         {
8641         case eEncodingT1:
8642             Rd = Rn = Bits32(opcode, 2, 0);
8643             Rm = Bits32(opcode, 5, 3);
8644             setflags = !InITBlock();
8645             shift_t = SRType_LSL;
8646             shift_n = 0;
8647             break;
8648         case eEncodingT2:
8649             Rd = Bits32(opcode, 11, 8);
8650             Rn = Bits32(opcode, 19, 16);
8651             Rm = Bits32(opcode, 3, 0);
8652             setflags = BitIsSet(opcode, 20);
8653             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8654             // if Rn == '1111' then SEE MOV (register);
8655             if (Rn == 15)
8656                 return EmulateMOVRdRm (opcode, eEncodingT3);
8657             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8658                 return false;
8659             break;
8660         case eEncodingA1:
8661             Rd = Bits32(opcode, 15, 12);
8662             Rn = Bits32(opcode, 19, 16);
8663             Rm = Bits32(opcode, 3, 0);
8664             setflags = BitIsSet(opcode, 20);
8665             shift_n = DecodeImmShiftARM(opcode, shift_t);
8666 
8667             if (Rd == 15 && setflags)
8668                 return EmulateSUBSPcLrEtc (opcode, encoding);
8669             break;
8670         default:
8671             return false;
8672         }
8673 
8674         // Read the first operand.
8675         uint32_t val1 = ReadCoreReg(Rn, &success);
8676         if (!success)
8677             return false;
8678 
8679         // Read the second operand.
8680         uint32_t val2 = ReadCoreReg(Rm, &success);
8681         if (!success)
8682             return false;
8683 
8684         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8685         if (!success)
8686             return false;
8687         uint32_t result = val1 | shifted;
8688 
8689         EmulateInstruction::Context context;
8690         context.type = EmulateInstruction::eContextImmediate;
8691         context.SetNoArgs ();
8692 
8693         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8694             return false;
8695     }
8696     return true;
8697 }
8698 
8699 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8700 // the destination register. It can optionally update the condition flags based on the result.
8701 bool
8702 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8703 {
8704 #if 0
8705     // ARM pseudo code...
8706     if ConditionPassed() then
8707         EncodingSpecificOperations();
8708         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8709         if d == 15 then         // Can only occur for ARM encoding
8710             ALUWritePC(result); // setflags is always FALSE here
8711         else
8712             R[d] = result;
8713             if setflags then
8714                 APSR.N = result<31>;
8715                 APSR.Z = IsZeroBit(result);
8716                 APSR.C = carry;
8717                 APSR.V = overflow;
8718 #endif
8719 
8720     bool success = false;
8721 
8722     uint32_t Rd; // the destination register
8723     uint32_t Rn; // the first operand
8724     bool setflags;
8725     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8726     switch (encoding) {
8727     case eEncodingT1:
8728         Rd = Bits32(opcode, 2, 0);
8729         Rn = Bits32(opcode, 5, 3);
8730         setflags = !InITBlock();
8731         imm32 = 0;
8732         break;
8733     case eEncodingT2:
8734         Rd = Bits32(opcode, 11, 8);
8735         Rn = Bits32(opcode, 19, 16);
8736         setflags = BitIsSet(opcode, 20);
8737         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8738         if (BadReg(Rd) || BadReg(Rn))
8739             return false;
8740         break;
8741     case eEncodingA1:
8742         Rd = Bits32(opcode, 15, 12);
8743         Rn = Bits32(opcode, 19, 16);
8744         setflags = BitIsSet(opcode, 20);
8745         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8746 
8747         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8748         if (Rd == 15 && setflags)
8749             return EmulateSUBSPcLrEtc (opcode, encoding);
8750         break;
8751     default:
8752         return false;
8753     }
8754     // Read the register value from the operand register Rn.
8755     uint32_t reg_val = ReadCoreReg(Rn, &success);
8756     if (!success)
8757         return false;
8758 
8759     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8760 
8761     EmulateInstruction::Context context;
8762     context.type = EmulateInstruction::eContextImmediate;
8763     context.SetNoArgs ();
8764 
8765     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8766         return false;
8767 
8768     return true;
8769 }
8770 
8771 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8772 // result to the destination register. It can optionally update the condition flags based on the result.
8773 bool
8774 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8775 {
8776 #if 0
8777     // ARM pseudo code...
8778     if ConditionPassed() then
8779         EncodingSpecificOperations();
8780         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8781         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8782         if d == 15 then         // Can only occur for ARM encoding
8783             ALUWritePC(result); // setflags is always FALSE here
8784         else
8785             R[d] = result;
8786             if setflags then
8787                 APSR.N = result<31>;
8788                 APSR.Z = IsZeroBit(result);
8789                 APSR.C = carry;
8790                 APSR.V = overflow;
8791 #endif
8792 
8793     bool success = false;
8794 
8795     uint32_t Rd; // the destination register
8796     uint32_t Rn; // the first operand
8797     uint32_t Rm; // the second operand
8798     bool setflags;
8799     ARM_ShifterType shift_t;
8800     uint32_t shift_n; // the shift applied to the value read from Rm
8801     switch (encoding) {
8802     case eEncodingT1:
8803         Rd = Bits32(opcode, 11, 8);
8804         Rn = Bits32(opcode, 19, 16);
8805         Rm = Bits32(opcode, 3, 0);
8806         setflags = BitIsSet(opcode, 20);
8807         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8808         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8809         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8810             return false;
8811         break;
8812     case eEncodingA1:
8813         Rd = Bits32(opcode, 15, 12);
8814         Rn = Bits32(opcode, 19, 16);
8815         Rm = Bits32(opcode, 3, 0);
8816         setflags = BitIsSet(opcode, 20);
8817         shift_n = DecodeImmShiftARM(opcode, shift_t);
8818 
8819         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8820         if (Rd == 15 && setflags)
8821             return EmulateSUBSPcLrEtc (opcode, encoding);
8822         break;
8823     default:
8824         return false;
8825     }
8826     // Read the register value from register Rn.
8827     uint32_t val1 = ReadCoreReg(Rn, &success);
8828     if (!success)
8829         return false;
8830 
8831     // Read the register value from register Rm.
8832     uint32_t val2 = ReadCoreReg(Rm, &success);
8833     if (!success)
8834         return false;
8835 
8836     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8837     if (!success)
8838         return false;
8839     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8840 
8841     EmulateInstruction::Context context;
8842     context.type = EmulateInstruction::eContextImmediate;
8843     context.SetNoArgs();
8844     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8845         return false;
8846 
8847     return true;
8848 }
8849 
8850 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8851 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8852 // flags based on the result.
8853 bool
8854 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8855 {
8856 #if 0
8857     // ARM pseudo code...
8858     if ConditionPassed() then
8859         EncodingSpecificOperations();
8860         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8861         if d == 15 then
8862             ALUWritePC(result); // setflags is always FALSE here
8863         else
8864             R[d] = result;
8865             if setflags then
8866                 APSR.N = result<31>;
8867                 APSR.Z = IsZeroBit(result);
8868                 APSR.C = carry;
8869                 APSR.V = overflow;
8870 #endif
8871 
8872     bool success = false;
8873 
8874     uint32_t Rd; // the destination register
8875     uint32_t Rn; // the first operand
8876     bool setflags;
8877     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8878     switch (encoding) {
8879     case eEncodingA1:
8880         Rd = Bits32(opcode, 15, 12);
8881         Rn = Bits32(opcode, 19, 16);
8882         setflags = BitIsSet(opcode, 20);
8883         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8884 
8885         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8886         if (Rd == 15 && setflags)
8887             return EmulateSUBSPcLrEtc  (opcode, encoding);
8888         break;
8889     default:
8890         return false;
8891     }
8892     // Read the register value from the operand register Rn.
8893     uint32_t reg_val = ReadCoreReg(Rn, &success);
8894     if (!success)
8895         return false;
8896 
8897     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8898 
8899     EmulateInstruction::Context context;
8900     context.type = EmulateInstruction::eContextImmediate;
8901     context.SetNoArgs ();
8902 
8903     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8904         return false;
8905 
8906     return true;
8907 }
8908 
8909 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8910 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8911 // condition flags based on the result.
8912 bool
8913 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8914 {
8915 #if 0
8916     // ARM pseudo code...
8917     if ConditionPassed() then
8918         EncodingSpecificOperations();
8919         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8920         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8921         if d == 15 then
8922             ALUWritePC(result); // setflags is always FALSE here
8923         else
8924             R[d] = result;
8925             if setflags then
8926                 APSR.N = result<31>;
8927                 APSR.Z = IsZeroBit(result);
8928                 APSR.C = carry;
8929                 APSR.V = overflow;
8930 #endif
8931 
8932     bool success = false;
8933 
8934     uint32_t Rd; // the destination register
8935     uint32_t Rn; // the first operand
8936     uint32_t Rm; // the second operand
8937     bool setflags;
8938     ARM_ShifterType shift_t;
8939     uint32_t shift_n; // the shift applied to the value read from Rm
8940     switch (encoding) {
8941     case eEncodingA1:
8942         Rd = Bits32(opcode, 15, 12);
8943         Rn = Bits32(opcode, 19, 16);
8944         Rm = Bits32(opcode, 3, 0);
8945         setflags = BitIsSet(opcode, 20);
8946         shift_n = DecodeImmShiftARM(opcode, shift_t);
8947 
8948         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8949         if (Rd == 15 && setflags)
8950             return EmulateSUBSPcLrEtc (opcode, encoding);
8951         break;
8952     default:
8953         return false;
8954     }
8955     // Read the register value from register Rn.
8956     uint32_t val1 = ReadCoreReg(Rn, &success);
8957     if (!success)
8958         return false;
8959 
8960     // Read the register value from register Rm.
8961     uint32_t val2 = ReadCoreReg(Rm, &success);
8962     if (!success)
8963         return false;
8964 
8965     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8966     if (!success)
8967         return false;
8968     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8969 
8970     EmulateInstruction::Context context;
8971     context.type = EmulateInstruction::eContextImmediate;
8972     context.SetNoArgs();
8973     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8974         return false;
8975 
8976     return true;
8977 }
8978 
8979 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8980 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8981 // It can optionally update the condition flags based on the result.
8982 bool
8983 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8984 {
8985 #if 0
8986     // ARM pseudo code...
8987     if ConditionPassed() then
8988         EncodingSpecificOperations();
8989         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8990         if d == 15 then         // Can only occur for ARM encoding
8991             ALUWritePC(result); // setflags is always FALSE here
8992         else
8993             R[d] = result;
8994             if setflags then
8995                 APSR.N = result<31>;
8996                 APSR.Z = IsZeroBit(result);
8997                 APSR.C = carry;
8998                 APSR.V = overflow;
8999 #endif
9000 
9001     bool success = false;
9002 
9003     uint32_t Rd; // the destination register
9004     uint32_t Rn; // the first operand
9005     bool setflags;
9006     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
9007     switch (encoding) {
9008     case eEncodingT1:
9009         Rd = Bits32(opcode, 11, 8);
9010         Rn = Bits32(opcode, 19, 16);
9011         setflags = BitIsSet(opcode, 20);
9012         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9013         if (BadReg(Rd) || BadReg(Rn))
9014             return false;
9015         break;
9016     case eEncodingA1:
9017         Rd = Bits32(opcode, 15, 12);
9018         Rn = Bits32(opcode, 19, 16);
9019         setflags = BitIsSet(opcode, 20);
9020         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9021 
9022         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9023         if (Rd == 15 && setflags)
9024             return EmulateSUBSPcLrEtc (opcode, encoding);
9025         break;
9026     default:
9027         return false;
9028     }
9029     // Read the register value from the operand register Rn.
9030     uint32_t reg_val = ReadCoreReg(Rn, &success);
9031     if (!success)
9032         return false;
9033 
9034     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9035 
9036     EmulateInstruction::Context context;
9037     context.type = EmulateInstruction::eContextImmediate;
9038     context.SetNoArgs ();
9039 
9040     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9041         return false;
9042 
9043     return true;
9044 }
9045 
9046 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
9047 // NOT (Carry flag) from a register value, and writes the result to the destination register.
9048 // It can optionally update the condition flags based on the result.
9049 bool
9050 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
9051 {
9052 #if 0
9053     // ARM pseudo code...
9054     if ConditionPassed() then
9055         EncodingSpecificOperations();
9056         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9057         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9058         if d == 15 then         // Can only occur for ARM encoding
9059             ALUWritePC(result); // setflags is always FALSE here
9060         else
9061             R[d] = result;
9062             if setflags then
9063                 APSR.N = result<31>;
9064                 APSR.Z = IsZeroBit(result);
9065                 APSR.C = carry;
9066                 APSR.V = overflow;
9067 #endif
9068 
9069     bool success = false;
9070 
9071     uint32_t Rd; // the destination register
9072     uint32_t Rn; // the first operand
9073     uint32_t Rm; // the second operand
9074     bool setflags;
9075     ARM_ShifterType shift_t;
9076     uint32_t shift_n; // the shift applied to the value read from Rm
9077     switch (encoding) {
9078     case eEncodingT1:
9079         Rd = Rn = Bits32(opcode, 2, 0);
9080         Rm = Bits32(opcode, 5, 3);
9081         setflags = !InITBlock();
9082         shift_t = SRType_LSL;
9083         shift_n = 0;
9084         break;
9085     case eEncodingT2:
9086         Rd = Bits32(opcode, 11, 8);
9087         Rn = Bits32(opcode, 19, 16);
9088         Rm = Bits32(opcode, 3, 0);
9089         setflags = BitIsSet(opcode, 20);
9090         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9091         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9092             return false;
9093         break;
9094     case eEncodingA1:
9095         Rd = Bits32(opcode, 15, 12);
9096         Rn = Bits32(opcode, 19, 16);
9097         Rm = Bits32(opcode, 3, 0);
9098         setflags = BitIsSet(opcode, 20);
9099         shift_n = DecodeImmShiftARM(opcode, shift_t);
9100 
9101         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9102         if (Rd == 15 && setflags)
9103             return EmulateSUBSPcLrEtc (opcode, encoding);
9104         break;
9105     default:
9106         return false;
9107     }
9108     // Read the register value from register Rn.
9109     uint32_t val1 = ReadCoreReg(Rn, &success);
9110     if (!success)
9111         return false;
9112 
9113     // Read the register value from register Rm.
9114     uint32_t val2 = ReadCoreReg(Rm, &success);
9115     if (!success)
9116         return false;
9117 
9118     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9119     if (!success)
9120         return false;
9121     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9122 
9123     EmulateInstruction::Context context;
9124     context.type = EmulateInstruction::eContextImmediate;
9125     context.SetNoArgs();
9126     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9127         return false;
9128 
9129     return true;
9130 }
9131 
9132 // This instruction subtracts an immediate value from a register value, and writes the result
9133 // to the destination register.  It can optionally update the condition flags based on the result.
9134 bool
9135 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9136 {
9137 #if 0
9138     // ARM pseudo code...
9139     if ConditionPassed() then
9140         EncodingSpecificOperations();
9141         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9142         R[d] = result;
9143         if setflags then
9144             APSR.N = result<31>;
9145             APSR.Z = IsZeroBit(result);
9146             APSR.C = carry;
9147             APSR.V = overflow;
9148 #endif
9149 
9150     bool success = false;
9151 
9152     uint32_t Rd; // the destination register
9153     uint32_t Rn; // the first operand
9154     bool setflags;
9155     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9156     switch (encoding) {
9157     case eEncodingT1:
9158         Rd = Bits32(opcode, 2, 0);
9159         Rn = Bits32(opcode, 5, 3);
9160         setflags = !InITBlock();
9161         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9162         break;
9163     case eEncodingT2:
9164         Rd = Rn = Bits32(opcode, 10, 8);
9165         setflags = !InITBlock();
9166         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9167         break;
9168     case eEncodingT3:
9169         Rd = Bits32(opcode, 11, 8);
9170         Rn = Bits32(opcode, 19, 16);
9171         setflags = BitIsSet(opcode, 20);
9172         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9173 
9174         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9175         if (Rd == 15 && setflags)
9176             return EmulateCMPImm (opcode, eEncodingT2);
9177 
9178         // if Rn == '1101' then SEE SUB (SP minus immediate);
9179         if (Rn == 13)
9180             return EmulateSUBSPImm (opcode, eEncodingT2);
9181 
9182         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9183         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9184             return false;
9185         break;
9186     case eEncodingT4:
9187         Rd = Bits32(opcode, 11, 8);
9188         Rn = Bits32(opcode, 19, 16);
9189         setflags = BitIsSet(opcode, 20);
9190         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9191 
9192         // if Rn == '1111' then SEE ADR;
9193         if (Rn == 15)
9194             return EmulateADR (opcode, eEncodingT2);
9195 
9196         // if Rn == '1101' then SEE SUB (SP minus immediate);
9197         if (Rn == 13)
9198             return EmulateSUBSPImm (opcode, eEncodingT3);
9199 
9200         if (BadReg(Rd))
9201             return false;
9202         break;
9203     default:
9204         return false;
9205     }
9206     // Read the register value from the operand register Rn.
9207     uint32_t reg_val = ReadCoreReg(Rn, &success);
9208     if (!success)
9209         return false;
9210 
9211     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9212 
9213     EmulateInstruction::Context context;
9214     context.type = EmulateInstruction::eContextImmediate;
9215     context.SetNoArgs ();
9216 
9217     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9218         return false;
9219 
9220     return true;
9221 }
9222 
9223 // This instruction subtracts an immediate value from a register value, and writes the result
9224 // to the destination register.  It can optionally update the condition flags based on the result.
9225 bool
9226 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9227 {
9228 #if 0
9229     // ARM pseudo code...
9230     if ConditionPassed() then
9231         EncodingSpecificOperations();
9232         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9233         if d == 15 then
9234             ALUWritePC(result); // setflags is always FALSE here
9235         else
9236             R[d] = result;
9237             if setflags then
9238                 APSR.N = result<31>;
9239                 APSR.Z = IsZeroBit(result);
9240                 APSR.C = carry;
9241                 APSR.V = overflow;
9242 #endif
9243 
9244     bool success = false;
9245 
9246     if (ConditionPassed(opcode))
9247     {
9248         uint32_t Rd; // the destination register
9249         uint32_t Rn; // the first operand
9250         bool setflags;
9251         uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9252         switch (encoding) {
9253         case eEncodingA1:
9254             Rd = Bits32(opcode, 15, 12);
9255             Rn = Bits32(opcode, 19, 16);
9256             setflags = BitIsSet(opcode, 20);
9257             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9258 
9259             // if Rn == '1111' && S == '0' then SEE ADR;
9260             if (Rn == 15 && !setflags)
9261                 return EmulateADR (opcode, eEncodingA2);
9262 
9263             // if Rn == '1101' then SEE SUB (SP minus immediate);
9264             if (Rn == 13)
9265                 return EmulateSUBSPImm (opcode, eEncodingA1);
9266 
9267             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9268             if (Rd == 15 && setflags)
9269                 return EmulateSUBSPcLrEtc (opcode, encoding);
9270             break;
9271         default:
9272             return false;
9273         }
9274         // Read the register value from the operand register Rn.
9275         uint32_t reg_val = ReadCoreReg(Rn, &success);
9276         if (!success)
9277             return false;
9278 
9279         AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9280 
9281         EmulateInstruction::Context context;
9282         if (Rd == 13)
9283             context.type = EmulateInstruction::eContextAdjustStackPointer;
9284         else
9285             context.type = EmulateInstruction::eContextRegisterPlusOffset;
9286 
9287         RegisterInfo dwarf_reg;
9288         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
9289         int64_t imm32_signed = imm32;
9290         context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed);
9291 
9292         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9293             return false;
9294     }
9295     return true;
9296 }
9297 
9298 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9299 // immediate value.  It updates the condition flags based on the result, and discards the result.
9300 bool
9301 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9302 {
9303 #if 0
9304     // ARM pseudo code...
9305     if ConditionPassed() then
9306         EncodingSpecificOperations();
9307         result = R[n] EOR imm32;
9308         APSR.N = result<31>;
9309         APSR.Z = IsZeroBit(result);
9310         APSR.C = carry;
9311         // APSR.V unchanged
9312 #endif
9313 
9314     bool success = false;
9315 
9316     if (ConditionPassed(opcode))
9317     {
9318         uint32_t Rn;
9319         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9320         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9321         switch (encoding)
9322         {
9323         case eEncodingT1:
9324             Rn = Bits32(opcode, 19, 16);
9325             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9326             if (BadReg(Rn))
9327                 return false;
9328             break;
9329         case eEncodingA1:
9330             Rn = Bits32(opcode, 19, 16);
9331             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9332             break;
9333         default:
9334             return false;
9335         }
9336 
9337         // Read the first operand.
9338         uint32_t val1 = ReadCoreReg(Rn, &success);
9339         if (!success)
9340             return false;
9341 
9342         uint32_t result = val1 ^ imm32;
9343 
9344         EmulateInstruction::Context context;
9345         context.type = EmulateInstruction::eContextImmediate;
9346         context.SetNoArgs ();
9347 
9348         if (!WriteFlags(context, result, carry))
9349             return false;
9350     }
9351     return true;
9352 }
9353 
9354 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9355 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9356 // the result.
9357 bool
9358 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9359 {
9360 #if 0
9361     // ARM pseudo code...
9362     if ConditionPassed() then
9363         EncodingSpecificOperations();
9364         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9365         result = R[n] EOR shifted;
9366         APSR.N = result<31>;
9367         APSR.Z = IsZeroBit(result);
9368         APSR.C = carry;
9369         // APSR.V unchanged
9370 #endif
9371 
9372     bool success = false;
9373 
9374     if (ConditionPassed(opcode))
9375     {
9376         uint32_t Rn, Rm;
9377         ARM_ShifterType shift_t;
9378         uint32_t shift_n; // the shift applied to the value read from Rm
9379         uint32_t carry;
9380         switch (encoding)
9381         {
9382         case eEncodingT1:
9383             Rn = Bits32(opcode, 19, 16);
9384             Rm = Bits32(opcode, 3, 0);
9385             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9386             if (BadReg(Rn) || BadReg(Rm))
9387                 return false;
9388             break;
9389         case eEncodingA1:
9390             Rn = Bits32(opcode, 19, 16);
9391             Rm = Bits32(opcode, 3, 0);
9392             shift_n = DecodeImmShiftARM(opcode, shift_t);
9393             break;
9394         default:
9395             return false;
9396         }
9397 
9398         // Read the first operand.
9399         uint32_t val1 = ReadCoreReg(Rn, &success);
9400         if (!success)
9401             return false;
9402 
9403         // Read the second operand.
9404         uint32_t val2 = ReadCoreReg(Rm, &success);
9405         if (!success)
9406             return false;
9407 
9408         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9409         if (!success)
9410             return false;
9411         uint32_t result = val1 ^ shifted;
9412 
9413         EmulateInstruction::Context context;
9414         context.type = EmulateInstruction::eContextImmediate;
9415         context.SetNoArgs ();
9416 
9417         if (!WriteFlags(context, result, carry))
9418             return false;
9419     }
9420     return true;
9421 }
9422 
9423 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9424 // It updates the condition flags based on the result, and discards the result.
9425 bool
9426 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9427 {
9428 #if 0
9429     // ARM pseudo code...
9430     if ConditionPassed() then
9431         EncodingSpecificOperations();
9432         result = R[n] AND imm32;
9433         APSR.N = result<31>;
9434         APSR.Z = IsZeroBit(result);
9435         APSR.C = carry;
9436         // APSR.V unchanged
9437 #endif
9438 
9439     bool success = false;
9440 
9441     if (ConditionPassed(opcode))
9442     {
9443         uint32_t Rn;
9444         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9445         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9446         switch (encoding)
9447         {
9448         case eEncodingT1:
9449             Rn = Bits32(opcode, 19, 16);
9450             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9451             if (BadReg(Rn))
9452                 return false;
9453             break;
9454         case eEncodingA1:
9455             Rn = Bits32(opcode, 19, 16);
9456             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9457             break;
9458         default:
9459             return false;
9460         }
9461 
9462         // Read the first operand.
9463         uint32_t val1 = ReadCoreReg(Rn, &success);
9464         if (!success)
9465             return false;
9466 
9467         uint32_t result = val1 & imm32;
9468 
9469         EmulateInstruction::Context context;
9470         context.type = EmulateInstruction::eContextImmediate;
9471         context.SetNoArgs ();
9472 
9473         if (!WriteFlags(context, result, carry))
9474             return false;
9475     }
9476     return true;
9477 }
9478 
9479 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9480 // It updates the condition flags based on the result, and discards the result.
9481 bool
9482 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9483 {
9484 #if 0
9485     // ARM pseudo code...
9486     if ConditionPassed() then
9487         EncodingSpecificOperations();
9488         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9489         result = R[n] AND shifted;
9490         APSR.N = result<31>;
9491         APSR.Z = IsZeroBit(result);
9492         APSR.C = carry;
9493         // APSR.V unchanged
9494 #endif
9495 
9496     bool success = false;
9497 
9498     if (ConditionPassed(opcode))
9499     {
9500         uint32_t Rn, Rm;
9501         ARM_ShifterType shift_t;
9502         uint32_t shift_n; // the shift applied to the value read from Rm
9503         uint32_t carry;
9504         switch (encoding)
9505         {
9506         case eEncodingT1:
9507             Rn = Bits32(opcode, 2, 0);
9508             Rm = Bits32(opcode, 5, 3);
9509             shift_t = SRType_LSL;
9510             shift_n = 0;
9511             break;
9512         case eEncodingT2:
9513             Rn = Bits32(opcode, 19, 16);
9514             Rm = Bits32(opcode, 3, 0);
9515             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9516             if (BadReg(Rn) || BadReg(Rm))
9517                 return false;
9518             break;
9519         case eEncodingA1:
9520             Rn = Bits32(opcode, 19, 16);
9521             Rm = Bits32(opcode, 3, 0);
9522             shift_n = DecodeImmShiftARM(opcode, shift_t);
9523             break;
9524         default:
9525             return false;
9526         }
9527 
9528         // Read the first operand.
9529         uint32_t val1 = ReadCoreReg(Rn, &success);
9530         if (!success)
9531             return false;
9532 
9533         // Read the second operand.
9534         uint32_t val2 = ReadCoreReg(Rm, &success);
9535         if (!success)
9536             return false;
9537 
9538         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9539         if (!success)
9540             return false;
9541         uint32_t result = val1 & shifted;
9542 
9543         EmulateInstruction::Context context;
9544         context.type = EmulateInstruction::eContextImmediate;
9545         context.SetNoArgs ();
9546 
9547         if (!WriteFlags(context, result, carry))
9548             return false;
9549     }
9550     return true;
9551 }
9552 
9553 // A8.6.216 SUB (SP minus register)
9554 bool
9555 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9556 {
9557 #if 0
9558     if ConditionPassed() then
9559         EncodingSpecificOperations();
9560         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9561         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9562         if d == 15 then // Can only occur for ARM encoding
9563             ALUWritePC(result); // setflags is always FALSE here
9564         else
9565             R[d] = result;
9566             if setflags then
9567                 APSR.N = result<31>;
9568                 APSR.Z = IsZeroBit(result);
9569                 APSR.C = carry;
9570                 APSR.V = overflow;
9571 #endif
9572 
9573     bool success = false;
9574 
9575     if (ConditionPassed(opcode))
9576     {
9577         uint32_t d;
9578         uint32_t m;
9579         bool setflags;
9580         ARM_ShifterType shift_t;
9581         uint32_t shift_n;
9582 
9583         switch (encoding)
9584         {
9585             case eEncodingT1:
9586                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9587                 d = Bits32 (opcode, 11, 8);
9588                 m = Bits32 (opcode, 3, 0);
9589                 setflags = BitIsSet (opcode, 20);
9590 
9591                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9592                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9593 
9594                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9595                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9596                     return false;
9597 
9598                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9599                 if ((d == 15) || BadReg (m))
9600                     return false;
9601                 break;
9602 
9603             case eEncodingA1:
9604                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9605                 d = Bits32 (opcode, 15, 12);
9606                 m = Bits32 (opcode, 3, 0);
9607                 setflags = BitIsSet (opcode, 20);
9608 
9609                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9610                 if (d == 15 && setflags)
9611                     EmulateSUBSPcLrEtc (opcode, encoding);
9612 
9613                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9614                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9615                 break;
9616 
9617             default:
9618                 return false;
9619         }
9620 
9621         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9622         uint32_t Rm = ReadCoreReg (m, &success);
9623         if (!success)
9624             return false;
9625 
9626         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9627         if (!success)
9628             return false;
9629 
9630         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9631         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9632         if (!success)
9633             return false;
9634 
9635         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9636 
9637         EmulateInstruction::Context context;
9638         context.type = eContextArithmetic;
9639         RegisterInfo sp_reg;
9640         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9641         RegisterInfo dwarf_reg;
9642         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9643         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9644 
9645         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9646             return false;
9647     }
9648     return true;
9649 }
9650 
9651 
9652 // A8.6.7 ADD (register-shifted register)
9653 bool
9654 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9655 {
9656 #if 0
9657     if ConditionPassed() then
9658         EncodingSpecificOperations();
9659         shift_n = UInt(R[s]<7:0>);
9660         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9661         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9662         R[d] = result;
9663         if setflags then
9664             APSR.N = result<31>;
9665             APSR.Z = IsZeroBit(result);
9666             APSR.C = carry;
9667             APSR.V = overflow;
9668 #endif
9669 
9670     bool success = false;
9671 
9672     if (ConditionPassed(opcode))
9673     {
9674         uint32_t d;
9675         uint32_t n;
9676         uint32_t m;
9677         uint32_t s;
9678         bool setflags;
9679         ARM_ShifterType shift_t;
9680 
9681         switch (encoding)
9682         {
9683             case eEncodingA1:
9684                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9685                 d = Bits32 (opcode, 15, 12);
9686                 n = Bits32 (opcode, 19, 16);
9687                 m = Bits32 (opcode, 3, 0);
9688                 s = Bits32 (opcode, 11, 8);
9689 
9690                 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
9691                 setflags = BitIsSet (opcode, 20);
9692                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9693 
9694                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9695                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9696                     return false;
9697                 break;
9698 
9699             default:
9700                 return false;
9701         }
9702 
9703         // shift_n = UInt(R[s]<7:0>);
9704         uint32_t Rs = ReadCoreReg (s, &success);
9705         if (!success)
9706             return false;
9707 
9708         uint32_t shift_n = Bits32 (Rs, 7, 0);
9709 
9710         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9711         uint32_t Rm = ReadCoreReg (m, &success);
9712         if (!success)
9713             return false;
9714 
9715         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9716         if (!success)
9717             return false;
9718 
9719         // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9720         uint32_t Rn = ReadCoreReg (n, &success);
9721         if (!success)
9722             return false;
9723 
9724         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9725 
9726         // R[d] = result;
9727         EmulateInstruction::Context context;
9728         context.type = eContextArithmetic;
9729         RegisterInfo reg_n;
9730         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9731         RegisterInfo reg_m;
9732         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9733 
9734         context.SetRegisterRegisterOperands (reg_n, reg_m);
9735 
9736         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9737             return false;
9738 
9739         // if setflags then
9740             // APSR.N = result<31>;
9741             // APSR.Z = IsZeroBit(result);
9742             // APSR.C = carry;
9743             // APSR.V = overflow;
9744         if (setflags)
9745             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9746     }
9747     return true;
9748 }
9749 
9750 // A8.6.213 SUB (register)
9751 bool
9752 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9753 {
9754 #if 0
9755     if ConditionPassed() then
9756         EncodingSpecificOperations();
9757         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9758         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9759         if d == 15 then // Can only occur for ARM encoding
9760             ALUWritePC(result); // setflags is always FALSE here
9761         else
9762             R[d] = result;
9763             if setflags then
9764                 APSR.N = result<31>;
9765                 APSR.Z = IsZeroBit(result);
9766                 APSR.C = carry;
9767                 APSR.V = overflow;
9768 #endif
9769 
9770     bool success = false;
9771 
9772     if (ConditionPassed(opcode))
9773     {
9774         uint32_t d;
9775         uint32_t n;
9776         uint32_t m;
9777         bool setflags;
9778         ARM_ShifterType shift_t;
9779         uint32_t shift_n;
9780 
9781         switch (encoding)
9782         {
9783             case eEncodingT1:
9784                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9785                 d = Bits32 (opcode, 2, 0);
9786                 n = Bits32 (opcode, 5, 3);
9787                 m = Bits32 (opcode, 8, 6);
9788                 setflags = !InITBlock();
9789 
9790                 // (shift_t, shift_n) = (SRType_LSL, 0);
9791                 shift_t = SRType_LSL;
9792                 shift_n = 0;
9793 
9794                 break;
9795 
9796             case eEncodingT2:
9797                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
9798                 d = Bits32 (opcode, 11, 8);
9799                 n = Bits32 (opcode, 19, 16);
9800                 m = Bits32 (opcode, 3, 0);
9801                 setflags = BitIsSet (opcode, 20);
9802 
9803                 // if Rd == "1111" && S == "1" then SEE CMP (register);
9804                 if (d == 15 && setflags == 1)
9805                     return EmulateCMPImm (opcode, eEncodingT3);
9806 
9807                 // if Rn == "1101" then SEE SUB (SP minus register);
9808                 if (n == 13)
9809                     return EmulateSUBSPReg (opcode, eEncodingT1);
9810 
9811                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9812                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9813 
9814                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9815                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9816                     return false;
9817 
9818                 break;
9819 
9820             case eEncodingA1:
9821                 // if Rn == '1101' then SEE SUB (SP minus register);
9822                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
9823                 d = Bits32 (opcode, 15, 12);
9824                 n = Bits32 (opcode, 19, 16);
9825                 m = Bits32 (opcode, 3, 0);
9826                 setflags = BitIsSet (opcode, 20);
9827 
9828                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9829                 if ((d == 15) && setflags)
9830                     EmulateSUBSPcLrEtc (opcode, encoding);
9831 
9832                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9833                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9834 
9835                 break;
9836 
9837             default:
9838                 return false;
9839         }
9840 
9841         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9842         uint32_t Rm = ReadCoreReg (m, &success);
9843         if (!success)
9844             return false;
9845 
9846         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9847         if (!success)
9848             return false;
9849 
9850         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9851         uint32_t Rn = ReadCoreReg (n, &success);
9852         if (!success)
9853             return false;
9854 
9855         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9856 
9857         // if d == 15 then // Can only occur for ARM encoding
9858             // ALUWritePC(result); // setflags is always FALSE here
9859         // else
9860             // R[d] = result;
9861             // if setflags then
9862                 // APSR.N = result<31>;
9863                 // APSR.Z = IsZeroBit(result);
9864                 // APSR.C = carry;
9865                 // APSR.V = overflow;
9866 
9867         EmulateInstruction::Context context;
9868         context.type = eContextArithmetic;
9869         RegisterInfo reg_n;
9870         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9871         RegisterInfo reg_m;
9872         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9873         context.SetRegisterRegisterOperands (reg_n, reg_m);
9874 
9875         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9876             return false;
9877     }
9878     return true;
9879 }
9880 
9881 // A8.6.202 STREX
9882 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9883 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9884 bool
9885 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9886 {
9887 #if 0
9888     if ConditionPassed() then
9889         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9890         address = R[n] + imm32;
9891         if ExclusiveMonitorsPass(address,4) then
9892             MemA[address,4] = R[t];
9893             R[d] = 0;
9894         else
9895             R[d] = 1;
9896 #endif
9897 
9898     bool success = false;
9899 
9900     if (ConditionPassed(opcode))
9901     {
9902         uint32_t d;
9903         uint32_t t;
9904         uint32_t n;
9905         uint32_t imm32;
9906         const uint32_t addr_byte_size = GetAddressByteSize();
9907 
9908         switch (encoding)
9909         {
9910             case eEncodingT1:
9911                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
9912                 d = Bits32 (opcode, 11, 8);
9913                 t = Bits32 (opcode, 15, 12);
9914                 n = Bits32 (opcode, 19, 16);
9915                 imm32 = Bits32 (opcode, 7, 0) << 2;
9916 
9917                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9918                 if (BadReg (d) || BadReg (t) || (n == 15))
9919                   return false;
9920 
9921                 // if d == n || d == t then UNPREDICTABLE;
9922                 if ((d == n) || (d == t))
9923                   return false;
9924 
9925                 break;
9926 
9927             case eEncodingA1:
9928                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9929                 d = Bits32 (opcode, 15, 12);
9930                 t = Bits32 (opcode, 3, 0);
9931                 n = Bits32 (opcode, 19, 16);
9932                 imm32 = 0;
9933 
9934                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9935                 if ((d == 15) || (t == 15) || (n == 15))
9936                     return false;
9937 
9938                 // if d == n || d == t then UNPREDICTABLE;
9939                 if ((d == n) || (d == t))
9940                     return false;
9941 
9942                 break;
9943 
9944             default:
9945                 return false;
9946         }
9947 
9948         // address = R[n] + imm32;
9949         uint32_t Rn = ReadCoreReg (n, &success);
9950         if (!success)
9951             return false;
9952 
9953         addr_t address = Rn + imm32;
9954 
9955         RegisterInfo base_reg;
9956         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9957         RegisterInfo data_reg;
9958         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9959         EmulateInstruction::Context context;
9960         context.type = eContextRegisterStore;
9961         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9962 
9963         // if ExclusiveMonitorsPass(address,4) then
9964         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9965         //                                                         always return true.
9966         if (true)
9967         {
9968             // MemA[address,4] = R[t];
9969             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9970             if (!success)
9971                 return false;
9972 
9973             if (!MemAWrite (context, address, Rt, addr_byte_size))
9974                 return false;
9975 
9976             // R[d] = 0;
9977             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9978                 return false;
9979         }
9980 #if 0 // unreachable because if true
9981         else
9982         {
9983             // R[d] = 1;
9984             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9985                 return false;
9986         }
9987 #endif // unreachable because if true
9988     }
9989     return true;
9990 }
9991 
9992 // A8.6.197 STRB (immediate, ARM)
9993 bool
9994 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9995 {
9996 #if 0
9997     if ConditionPassed() then
9998         EncodingSpecificOperations();
9999         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10000         address = if index then offset_addr else R[n];
10001         MemU[address,1] = R[t]<7:0>;
10002         if wback then R[n] = offset_addr;
10003 #endif
10004 
10005     bool success = false;
10006 
10007     if (ConditionPassed(opcode))
10008     {
10009         uint32_t t;
10010         uint32_t n;
10011         uint32_t imm32;
10012         bool index;
10013         bool add;
10014         bool wback;
10015 
10016         switch (encoding)
10017         {
10018             case eEncodingA1:
10019                 // if P == '0' && W == '1' then SEE STRBT;
10020                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10021                 t = Bits32 (opcode, 15, 12);
10022                 n = Bits32 (opcode, 19, 16);
10023                 imm32 = Bits32 (opcode, 11, 0);
10024 
10025                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10026                 index = BitIsSet (opcode, 24);
10027                 add = BitIsSet (opcode, 23);
10028                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10029 
10030                 // if t == 15 then UNPREDICTABLE;
10031                 if (t == 15)
10032                     return false;
10033 
10034                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10035                 if (wback && ((n == 15) || (n == t)))
10036                     return false;
10037 
10038                 break;
10039 
10040             default:
10041                 return false;
10042         }
10043 
10044         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10045         uint32_t Rn = ReadCoreReg (n, &success);
10046         if (!success)
10047             return false;
10048 
10049         addr_t offset_addr;
10050         if (add)
10051             offset_addr = Rn + imm32;
10052         else
10053             offset_addr = Rn - imm32;
10054 
10055         // address = if index then offset_addr else R[n];
10056         addr_t address;
10057         if (index)
10058             address = offset_addr;
10059         else
10060             address = Rn;
10061 
10062         // MemU[address,1] = R[t]<7:0>;
10063         uint32_t Rt = ReadCoreReg (t, &success);
10064         if (!success)
10065             return false;
10066 
10067         RegisterInfo base_reg;
10068         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10069         RegisterInfo data_reg;
10070         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10071         EmulateInstruction::Context context;
10072         context.type = eContextRegisterStore;
10073         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10074 
10075         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
10076             return false;
10077 
10078         // if wback then R[n] = offset_addr;
10079         if (wback)
10080         {
10081             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10082                 return false;
10083         }
10084     }
10085     return true;
10086 }
10087 
10088 // A8.6.194 STR (immediate, ARM)
10089 bool
10090 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
10091 {
10092 #if 0
10093     if ConditionPassed() then
10094         EncodingSpecificOperations();
10095         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10096         address = if index then offset_addr else R[n];
10097         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10098         if wback then R[n] = offset_addr;
10099 #endif
10100 
10101     bool success = false;
10102 
10103     if (ConditionPassed(opcode))
10104     {
10105         uint32_t t;
10106         uint32_t n;
10107         uint32_t imm32;
10108         bool index;
10109         bool add;
10110         bool wback;
10111 
10112         const uint32_t addr_byte_size = GetAddressByteSize();
10113 
10114         switch (encoding)
10115         {
10116             case eEncodingA1:
10117                 // if P == '0' && W == '1' then SEE STRT;
10118                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH;
10119                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10120                 t = Bits32 (opcode, 15, 12);
10121                 n = Bits32 (opcode, 19, 16);
10122                 imm32 = Bits32 (opcode, 11, 0);
10123 
10124                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10125                 index = BitIsSet (opcode, 24);
10126                 add = BitIsSet (opcode, 23);
10127                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10128 
10129                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10130                 if (wback && ((n == 15) || (n == t)))
10131                     return false;
10132 
10133                 break;
10134 
10135             default:
10136                 return false;
10137         }
10138 
10139         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10140         uint32_t Rn = ReadCoreReg (n, &success);
10141         if (!success)
10142             return false;
10143 
10144         addr_t offset_addr;
10145         if (add)
10146             offset_addr = Rn + imm32;
10147         else
10148             offset_addr = Rn - imm32;
10149 
10150         // address = if index then offset_addr else R[n];
10151         addr_t address;
10152         if (index)
10153             address = offset_addr;
10154         else
10155             address = Rn;
10156 
10157         RegisterInfo base_reg;
10158         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10159         RegisterInfo data_reg;
10160         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10161         EmulateInstruction::Context context;
10162         context.type = eContextRegisterStore;
10163         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10164 
10165         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10166         uint32_t Rt = ReadCoreReg (t, &success);
10167         if (!success)
10168             return false;
10169 
10170         if (t == 15)
10171         {
10172             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10173             if (!success)
10174                 return false;
10175 
10176             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10177                 return false;
10178         }
10179         else
10180         {
10181             if (!MemUWrite (context, address, Rt, addr_byte_size))
10182                   return false;
10183         }
10184 
10185         // if wback then R[n] = offset_addr;
10186         if (wback)
10187         {
10188             context.type = eContextAdjustBaseRegister;
10189             context.SetImmediate (offset_addr);
10190 
10191             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10192                 return false;
10193         }
10194     }
10195     return true;
10196 }
10197 
10198 // A8.6.66 LDRD (immediate)
10199 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10200 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10201 bool
10202 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10203 {
10204 #if 0
10205     if ConditionPassed() then
10206         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10207         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10208         address = if index then offset_addr else R[n];
10209         R[t] = MemA[address,4];
10210         R[t2] = MemA[address+4,4];
10211         if wback then R[n] = offset_addr;
10212 #endif
10213 
10214     bool success = false;
10215 
10216     if (ConditionPassed(opcode))
10217     {
10218         uint32_t t;
10219         uint32_t t2;
10220         uint32_t n;
10221         uint32_t imm32;
10222         bool index;
10223         bool add;
10224         bool wback;
10225 
10226         switch (encoding)
10227         {
10228             case eEncodingT1:
10229                 //if P == '0' && W == '0' then SEE 'Related encodings';
10230                 //if Rn == '1111' then SEE LDRD (literal);
10231                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10232                 t = Bits32 (opcode, 15, 12);
10233                 t2 = Bits32 (opcode, 11, 8);
10234                 n = Bits32 (opcode, 19, 16);
10235                 imm32 = Bits32 (opcode, 7, 0) << 2;
10236 
10237                 //index = (P == '1'); add = (U == '1'); wback = (W == '1');
10238                 index = BitIsSet (opcode, 24);
10239                 add = BitIsSet (opcode, 23);
10240                 wback = BitIsSet (opcode, 21);
10241 
10242                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10243                 if (wback && ((n == t) || (n == t2)))
10244                     return false;
10245 
10246                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10247                 if (BadReg (t) || BadReg (t2) || (t == t2))
10248                     return false;
10249 
10250                 break;
10251 
10252             case eEncodingA1:
10253                 //if Rn == '1111' then SEE LDRD (literal);
10254                 //if Rt<0> == '1' then UNPREDICTABLE;
10255                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10256                 t = Bits32 (opcode, 15, 12);
10257                 if (BitIsSet (t, 0))
10258                     return false;
10259                 t2 = t + 1;
10260                 n = Bits32 (opcode, 19, 16);
10261                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10262 
10263                 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10264                 index = BitIsSet (opcode, 24);
10265                 add = BitIsSet (opcode, 23);
10266                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10267 
10268                 //if P == '0' && W == '1' then UNPREDICTABLE;
10269                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10270                     return false;
10271 
10272                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10273                 if (wback && ((n == t) || (n == t2)))
10274                     return false;
10275 
10276                 //if t2 == 15 then UNPREDICTABLE;
10277                 if (t2 == 15)
10278                     return false;
10279 
10280                 break;
10281 
10282             default:
10283                 return false;
10284         }
10285 
10286         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10287         uint32_t Rn = ReadCoreReg (n, &success);
10288         if (!success)
10289             return false;
10290 
10291         addr_t offset_addr;
10292         if (add)
10293                   offset_addr = Rn + imm32;
10294         else
10295             offset_addr = Rn - imm32;
10296 
10297         //address = if index then offset_addr else R[n];
10298         addr_t address;
10299         if (index)
10300             address = offset_addr;
10301         else
10302             address = Rn;
10303 
10304         //R[t] = MemA[address,4];
10305         RegisterInfo base_reg;
10306         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10307 
10308         EmulateInstruction::Context context;
10309         if (n == 13)
10310             context.type = eContextPopRegisterOffStack;
10311         else
10312             context.type = eContextRegisterLoad;
10313         context.SetAddress(address);
10314 
10315         const uint32_t addr_byte_size = GetAddressByteSize();
10316         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10317         if (!success)
10318             return false;
10319 
10320         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10321             return false;
10322 
10323         //R[t2] = MemA[address+4,4];
10324         context.SetAddress(address + 4);
10325         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10326         if (!success)
10327             return false;
10328 
10329         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10330             return false;
10331 
10332         //if wback then R[n] = offset_addr;
10333         if (wback)
10334         {
10335             context.type = eContextAdjustBaseRegister;
10336             context.SetAddress (offset_addr);
10337 
10338             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10339                 return false;
10340         }
10341     }
10342     return true;
10343 }
10344 
10345 // A8.6.68 LDRD (register)
10346 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10347 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10348 bool
10349 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10350 {
10351 #if 0
10352     if ConditionPassed() then
10353         EncodingSpecificOperations();
10354         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10355         address = if index then offset_addr else R[n];
10356         R[t] = MemA[address,4];
10357         R[t2] = MemA[address+4,4];
10358         if wback then R[n] = offset_addr;
10359 #endif
10360 
10361     bool success = false;
10362 
10363     if (ConditionPassed(opcode))
10364     {
10365         uint32_t t;
10366         uint32_t t2;
10367         uint32_t n;
10368         uint32_t m;
10369         bool index;
10370         bool add;
10371         bool wback;
10372 
10373         switch (encoding)
10374         {
10375             case eEncodingA1:
10376                 // if Rt<0> == '1' then UNPREDICTABLE;
10377                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10378                 t = Bits32 (opcode, 15, 12);
10379                 if (BitIsSet (t, 0))
10380                     return false;
10381                 t2 = t + 1;
10382                 n = Bits32 (opcode, 19, 16);
10383                 m = Bits32 (opcode, 3, 0);
10384 
10385                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10386                 index = BitIsSet (opcode, 24);
10387                 add = BitIsSet (opcode, 23);
10388                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10389 
10390                 // if P == '0' && W == '1' then UNPREDICTABLE;
10391                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10392                   return false;
10393 
10394                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10395                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10396                   return false;
10397 
10398                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10399                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10400                   return false;
10401 
10402                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10403                 if ((ArchVersion() < 6) && wback && (m == n))
10404                   return false;
10405                 break;
10406 
10407             default:
10408                 return false;
10409         }
10410 
10411         uint32_t Rn = ReadCoreReg (n, &success);
10412         if (!success)
10413             return false;
10414         RegisterInfo base_reg;
10415         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10416 
10417         uint32_t Rm = ReadCoreReg (m, &success);
10418         if (!success)
10419             return false;
10420         RegisterInfo offset_reg;
10421         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10422 
10423         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10424         addr_t offset_addr;
10425         if (add)
10426             offset_addr = Rn + Rm;
10427         else
10428             offset_addr = Rn - Rm;
10429 
10430         // address = if index then offset_addr else R[n];
10431         addr_t address;
10432         if (index)
10433             address = offset_addr;
10434         else
10435             address = Rn;
10436 
10437         EmulateInstruction::Context context;
10438         if (n == 13)
10439             context.type = eContextPopRegisterOffStack;
10440         else
10441             context.type = eContextRegisterLoad;
10442         context.SetAddress(address);
10443 
10444         // R[t] = MemA[address,4];
10445         const uint32_t addr_byte_size = GetAddressByteSize();
10446         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10447         if (!success)
10448             return false;
10449 
10450         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10451             return false;
10452 
10453         // R[t2] = MemA[address+4,4];
10454 
10455         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10456         if (!success)
10457             return false;
10458 
10459         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10460             return false;
10461 
10462         // if wback then R[n] = offset_addr;
10463         if (wback)
10464         {
10465             context.type = eContextAdjustBaseRegister;
10466             context.SetAddress (offset_addr);
10467 
10468             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10469                 return false;
10470         }
10471     }
10472     return true;
10473 }
10474 
10475 // A8.6.200 STRD (immediate)
10476 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10477 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10478 bool
10479 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10480 {
10481 #if 0
10482     if ConditionPassed() then
10483         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10484         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10485         address = if index then offset_addr else R[n];
10486         MemA[address,4] = R[t];
10487         MemA[address+4,4] = R[t2];
10488         if wback then R[n] = offset_addr;
10489 #endif
10490 
10491     bool success = false;
10492 
10493     if (ConditionPassed(opcode))
10494     {
10495         uint32_t t;
10496         uint32_t t2;
10497         uint32_t n;
10498         uint32_t imm32;
10499         bool index;
10500         bool add;
10501         bool wback;
10502 
10503         switch (encoding)
10504         {
10505             case eEncodingT1:
10506                 // if P == '0' && W == '0' then SEE 'Related encodings';
10507                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10508                 t = Bits32 (opcode, 15, 12);
10509                 t2 = Bits32 (opcode, 11, 8);
10510                 n = Bits32 (opcode, 19, 16);
10511                 imm32 = Bits32 (opcode, 7, 0) << 2;
10512 
10513                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10514                 index = BitIsSet (opcode, 24);
10515                 add = BitIsSet (opcode, 23);
10516                 wback = BitIsSet (opcode, 21);
10517 
10518                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10519                 if (wback && ((n == t) || (n == t2)))
10520                     return false;
10521 
10522                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10523                 if ((n == 15) || BadReg (t) || BadReg (t2))
10524                     return false;
10525 
10526                 break;
10527 
10528             case eEncodingA1:
10529                 // if Rt<0> == '1' then UNPREDICTABLE;
10530                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10531                 t = Bits32 (opcode, 15, 12);
10532                 if (BitIsSet (t, 0))
10533                     return false;
10534 
10535                 t2 = t + 1;
10536                 n = Bits32 (opcode, 19, 16);
10537                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10538 
10539                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10540                 index = BitIsSet (opcode, 24);
10541                 add = BitIsSet (opcode, 23);
10542                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10543 
10544                 // if P == '0' && W == '1' then UNPREDICTABLE;
10545                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10546                     return false;
10547 
10548                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10549                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10550                     return false;
10551 
10552                 // if t2 == 15 then UNPREDICTABLE;
10553                 if (t2 == 15)
10554                     return false;
10555 
10556                 break;
10557 
10558             default:
10559                 return false;
10560         }
10561 
10562         RegisterInfo base_reg;
10563         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10564 
10565         uint32_t Rn = ReadCoreReg (n, &success);
10566         if (!success)
10567             return false;
10568 
10569         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10570         addr_t offset_addr;
10571         if (add)
10572             offset_addr = Rn + imm32;
10573         else
10574             offset_addr = Rn - imm32;
10575 
10576         //address = if index then offset_addr else R[n];
10577         addr_t address;
10578         if (index)
10579             address = offset_addr;
10580         else
10581             address = Rn;
10582 
10583         //MemA[address,4] = R[t];
10584         RegisterInfo data_reg;
10585         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10586 
10587         uint32_t data = ReadCoreReg (t, &success);
10588         if (!success)
10589             return false;
10590 
10591         EmulateInstruction::Context context;
10592         if (n == 13)
10593             context.type = eContextPushRegisterOnStack;
10594         else
10595             context.type = eContextRegisterStore;
10596         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10597 
10598         const uint32_t addr_byte_size = GetAddressByteSize();
10599 
10600         if (!MemAWrite (context, address, data, addr_byte_size))
10601             return false;
10602 
10603         //MemA[address+4,4] = R[t2];
10604         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10605         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10606 
10607         data = ReadCoreReg (t2, &success);
10608         if (!success)
10609             return false;
10610 
10611         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10612             return false;
10613 
10614         //if wback then R[n] = offset_addr;
10615         if (wback)
10616         {
10617             context.type = eContextAdjustBaseRegister;
10618             context.SetAddress (offset_addr);
10619 
10620             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10621                 return false;
10622         }
10623     }
10624     return true;
10625 }
10626 
10627 
10628 // A8.6.201 STRD (register)
10629 bool
10630 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10631 {
10632 #if 0
10633     if ConditionPassed() then
10634         EncodingSpecificOperations();
10635         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10636         address = if index then offset_addr else R[n];
10637         MemA[address,4] = R[t];
10638         MemA[address+4,4] = R[t2];
10639         if wback then R[n] = offset_addr;
10640 #endif
10641 
10642     bool success = false;
10643 
10644     if (ConditionPassed(opcode))
10645     {
10646         uint32_t t;
10647         uint32_t t2;
10648         uint32_t n;
10649         uint32_t m;
10650         bool index;
10651         bool add;
10652         bool wback;
10653 
10654         switch (encoding)
10655         {
10656             case eEncodingA1:
10657                 // if Rt<0> == '1' then UNPREDICTABLE;
10658                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10659                 t = Bits32 (opcode, 15, 12);
10660                 if (BitIsSet (t, 0))
10661                    return false;
10662 
10663                 t2 = t+1;
10664                 n = Bits32 (opcode, 19, 16);
10665                 m = Bits32 (opcode, 3, 0);
10666 
10667                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10668                 index = BitIsSet (opcode, 24);
10669                 add = BitIsSet (opcode, 23);
10670                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10671 
10672                 // if P == '0' && W == '1' then UNPREDICTABLE;
10673                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10674                    return false;
10675 
10676                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10677                 if ((t2 == 15) || (m == 15))
10678                    return false;
10679 
10680                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10681                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10682                    return false;
10683 
10684                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10685                 if ((ArchVersion() < 6) && wback && (m == n))
10686                    return false;
10687 
10688                 break;
10689 
10690             default:
10691                 return false;
10692         }
10693 
10694         RegisterInfo base_reg;
10695         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10696         RegisterInfo offset_reg;
10697         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10698         RegisterInfo data_reg;
10699 
10700         uint32_t Rn = ReadCoreReg (n, &success);
10701         if (!success)
10702             return false;
10703 
10704         uint32_t Rm = ReadCoreReg (m, &success);
10705         if (!success)
10706             return false;
10707 
10708         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10709         addr_t offset_addr;
10710         if (add)
10711             offset_addr = Rn + Rm;
10712         else
10713             offset_addr = Rn - Rm;
10714 
10715         // address = if index then offset_addr else R[n];
10716         addr_t address;
10717         if (index)
10718             address = offset_addr;
10719         else
10720             address = Rn;
10721                           // MemA[address,4] = R[t];
10722         uint32_t Rt = ReadCoreReg (t, &success);
10723         if (!success)
10724             return false;
10725 
10726         EmulateInstruction::Context context;
10727         if (t == 13)
10728             context.type = eContextPushRegisterOnStack;
10729         else
10730             context.type = eContextRegisterStore;
10731 
10732         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10733         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10734 
10735         const uint32_t addr_byte_size = GetAddressByteSize();
10736 
10737         if (!MemAWrite (context, address, Rt, addr_byte_size))
10738             return false;
10739 
10740         // MemA[address+4,4] = R[t2];
10741         uint32_t Rt2 = ReadCoreReg (t2, &success);
10742         if (!success)
10743             return false;
10744 
10745         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10746 
10747         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10748 
10749         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10750             return false;
10751 
10752         // if wback then R[n] = offset_addr;
10753         if (wback)
10754         {
10755             context.type = eContextAdjustBaseRegister;
10756             context.SetAddress (offset_addr);
10757 
10758             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10759                 return false;
10760 
10761         }
10762     }
10763     return true;
10764 }
10765 
10766 // A8.6.319 VLDM
10767 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10768 // an ARM core register.
10769 bool
10770 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10771 {
10772 #if 0
10773     if ConditionPassed() then
10774         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10775         address = if add then R[n] else R[n]-imm32;
10776         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10777         for r = 0 to regs-1
10778             if single_regs then
10779                 S[d+r] = MemA[address,4]; address = address+4;
10780             else
10781                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10782                 // Combine the word-aligned words in the correct order for current endianness.
10783                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10784 #endif
10785 
10786     bool success = false;
10787 
10788     if (ConditionPassed(opcode))
10789     {
10790         bool single_regs;
10791         bool add;
10792         bool wback;
10793         uint32_t d;
10794         uint32_t n;
10795         uint32_t imm32;
10796         uint32_t regs;
10797 
10798         switch (encoding)
10799         {
10800             case eEncodingT1:
10801             case eEncodingA1:
10802                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10803                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10804                 // if P == '1' && W == '0' then SEE VLDR;
10805                 // if P == U && W == '1' then UNDEFINED;
10806                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10807                     return false;
10808 
10809                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10810                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
10811                 single_regs = false;
10812                 add = BitIsSet (opcode, 23);
10813                 wback = BitIsSet (opcode, 21);
10814 
10815                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10816                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10817                 n = Bits32 (opcode, 19, 16);
10818                 imm32 = Bits32 (opcode, 7, 0) << 2;
10819 
10820                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
10821                 regs = Bits32 (opcode, 7, 0) / 2;
10822 
10823                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10824                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10825                     return false;
10826 
10827                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10828                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10829                     return false;
10830 
10831                 break;
10832 
10833             case eEncodingT2:
10834             case eEncodingA2:
10835                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10836                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10837                 // if P == '1' && W == '0' then SEE VLDR;
10838                 // if P == U && W == '1' then UNDEFINED;
10839                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10840                     return false;
10841 
10842                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10843                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
10844                 single_regs = true;
10845                 add = BitIsSet (opcode, 23);
10846                 wback = BitIsSet (opcode, 21);
10847                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10848                 n = Bits32 (opcode, 19, 16);
10849 
10850                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
10851                 imm32 = Bits32 (opcode, 7, 0) << 2;
10852                 regs = Bits32 (opcode, 7, 0);
10853 
10854                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10855                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10856                     return false;
10857 
10858                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10859                 if ((regs == 0) || ((d + regs) > 32))
10860                     return false;
10861                 break;
10862 
10863             default:
10864                 return false;
10865         }
10866 
10867         RegisterInfo base_reg;
10868         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10869 
10870         uint32_t Rn = ReadCoreReg (n, &success);
10871         if (!success)
10872             return false;
10873 
10874         // address = if add then R[n] else R[n]-imm32;
10875         addr_t address;
10876         if (add)
10877             address = Rn;
10878         else
10879             address = Rn - imm32;
10880 
10881         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10882         EmulateInstruction::Context context;
10883 
10884         if (wback)
10885         {
10886             uint32_t value;
10887             if (add)
10888                 value = Rn + imm32;
10889             else
10890                 value = Rn - imm32;
10891 
10892             context.type = eContextAdjustBaseRegister;
10893             context.SetImmediateSigned (value - Rn);
10894             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10895                 return false;
10896 
10897         }
10898 
10899         const uint32_t addr_byte_size = GetAddressByteSize();
10900         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10901 
10902         context.type = eContextRegisterLoad;
10903 
10904         // for r = 0 to regs-1
10905         for (uint32_t r = 0; r < regs; ++r)
10906         {
10907             if (single_regs)
10908             {
10909                 // S[d+r] = MemA[address,4]; address = address+4;
10910                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10911 
10912                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10913                 if (!success)
10914                     return false;
10915 
10916                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10917                     return false;
10918 
10919                 address = address + 4;
10920             }
10921             else
10922             {
10923                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10924                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10925                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10926                 if (!success)
10927                     return false;
10928 
10929                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10930                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10931                 if (!success)
10932                     return false;
10933 
10934                 address = address + 8;
10935                 // // Combine the word-aligned words in the correct order for current endianness.
10936                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10937                 uint64_t data;
10938                 if (GetByteOrder() == eByteOrderBig)
10939                 {
10940                     data = word1;
10941                     data = (data << 32) | word2;
10942                 }
10943                 else
10944                 {
10945                     data = word2;
10946                     data = (data << 32) | word1;
10947                 }
10948 
10949                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10950                     return false;
10951             }
10952         }
10953     }
10954     return true;
10955 }
10956 
10957 // A8.6.399 VSTM
10958 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10959 // ARM core register.
10960 bool
10961 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10962 {
10963 #if 0
10964     if ConditionPassed() then
10965         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10966         address = if add then R[n] else R[n]-imm32;
10967         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10968         for r = 0 to regs-1
10969             if single_regs then
10970                 MemA[address,4] = S[d+r]; address = address+4;
10971             else
10972                 // Store as two word-aligned words in the correct order for current endianness.
10973                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10974                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10975                 address = address+8;
10976 #endif
10977 
10978     bool success = false;
10979 
10980     if (ConditionPassed (opcode))
10981     {
10982         bool single_regs;
10983         bool add;
10984         bool wback;
10985         uint32_t d;
10986         uint32_t n;
10987         uint32_t imm32;
10988         uint32_t regs;
10989 
10990         switch (encoding)
10991         {
10992             case eEncodingT1:
10993             case eEncodingA1:
10994                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10995                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
10996                 // if P == '1' && W == '0' then SEE VSTR;
10997                 // if P == U && W == '1' then UNDEFINED;
10998                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10999                     return false;
11000 
11001                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11002                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11003                 single_regs = false;
11004                 add = BitIsSet (opcode, 23);
11005                 wback = BitIsSet (opcode, 21);
11006 
11007                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11008                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11009                 n = Bits32 (opcode, 19, 16);
11010                 imm32 = Bits32 (opcode, 7, 0) << 2;
11011 
11012                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11013                 regs = Bits32 (opcode, 7, 0) / 2;
11014 
11015                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11016                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11017                     return false;
11018 
11019                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11020                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11021                     return false;
11022 
11023                 break;
11024 
11025             case eEncodingT2:
11026             case eEncodingA2:
11027                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11028                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11029                 // if P == '1' && W == '0' then SEE VSTR;
11030                 // if P == U && W == '1' then UNDEFINED;
11031                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11032                     return false;
11033 
11034                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11035                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
11036                 single_regs = true;
11037                 add = BitIsSet (opcode, 23);
11038                 wback = BitIsSet (opcode, 21);
11039                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11040                 n = Bits32 (opcode, 19, 16);
11041 
11042                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11043                 imm32 = Bits32 (opcode, 7, 0) << 2;
11044                 regs = Bits32 (opcode, 7, 0);
11045 
11046                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11047                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
11048                     return false;
11049 
11050                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11051                 if ((regs == 0) || ((d + regs) > 32))
11052                     return false;
11053 
11054                 break;
11055 
11056             default:
11057                 return false;
11058         }
11059 
11060         RegisterInfo base_reg;
11061         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11062 
11063         uint32_t Rn = ReadCoreReg (n, &success);
11064         if (!success)
11065             return false;
11066 
11067         // address = if add then R[n] else R[n]-imm32;
11068         addr_t address;
11069         if (add)
11070             address = Rn;
11071         else
11072             address = Rn - imm32;
11073 
11074         EmulateInstruction::Context context;
11075         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11076         if (wback)
11077         {
11078             uint32_t value;
11079             if (add)
11080                 value = Rn + imm32;
11081             else
11082                 value = Rn - imm32;
11083 
11084             context.type = eContextAdjustBaseRegister;
11085             context.SetRegisterPlusOffset (base_reg, value - Rn);
11086 
11087             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11088                 return false;
11089         }
11090 
11091         const uint32_t addr_byte_size = GetAddressByteSize();
11092         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11093 
11094         context.type = eContextRegisterStore;
11095         // for r = 0 to regs-1
11096         for (uint32_t r = 0; r < regs; ++r)
11097         {
11098 
11099             if (single_regs)
11100             {
11101                 // MemA[address,4] = S[d+r]; address = address+4;
11102                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11103                 if (!success)
11104                     return false;
11105 
11106                 RegisterInfo data_reg;
11107                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11108                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11109                 if (!MemAWrite (context, address, data, addr_byte_size))
11110                     return false;
11111 
11112                 address = address + 4;
11113             }
11114             else
11115             {
11116                 // // Store as two word-aligned words in the correct order for current endianness.
11117                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11118                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11119                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11120                 if (!success)
11121                     return false;
11122 
11123                 RegisterInfo data_reg;
11124                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11125 
11126                 if (GetByteOrder() == eByteOrderBig)
11127                 {
11128                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11129                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11130                         return false;
11131 
11132                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11133                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11134                         return false;
11135                 }
11136                 else
11137                 {
11138                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, 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, (address + 4) - Rn);
11143                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11144                         return false;
11145                 }
11146                 // address = address+8;
11147                 address = address + 8;
11148             }
11149         }
11150     }
11151     return true;
11152 }
11153 
11154 // A8.6.320
11155 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11156 // an optional offset.
11157 bool
11158 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11159 {
11160 #if 0
11161     if ConditionPassed() then
11162         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11163         base = if n == 15 then Align(PC,4) else R[n];
11164         address = if add then (base + imm32) else (base - imm32);
11165         if single_reg then
11166             S[d] = MemA[address,4];
11167         else
11168             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11169             // Combine the word-aligned words in the correct order for current endianness.
11170             D[d] = if BigEndian() then word1:word2 else word2:word1;
11171 #endif
11172 
11173     bool success = false;
11174 
11175     if (ConditionPassed (opcode))
11176     {
11177         bool single_reg;
11178         bool add;
11179         uint32_t imm32;
11180         uint32_t d;
11181         uint32_t n;
11182 
11183         switch (encoding)
11184         {
11185             case eEncodingT1:
11186             case eEncodingA1:
11187                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11188                 single_reg = false;
11189                 add = BitIsSet (opcode, 23);
11190                 imm32 = Bits32 (opcode, 7, 0) << 2;
11191 
11192                 // d = UInt(D:Vd); n = UInt(Rn);
11193                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11194                 n = Bits32 (opcode, 19, 16);
11195 
11196                 break;
11197 
11198             case eEncodingT2:
11199             case eEncodingA2:
11200                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11201                 single_reg = true;
11202                 add = BitIsSet (opcode, 23);
11203                 imm32 = Bits32 (opcode, 7, 0) << 2;
11204 
11205                 // d = UInt(Vd:D); n = UInt(Rn);
11206                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11207                 n = Bits32 (opcode, 19, 16);
11208 
11209                 break;
11210 
11211             default:
11212                 return false;
11213         }
11214         RegisterInfo base_reg;
11215         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11216 
11217         uint32_t Rn = ReadCoreReg (n, &success);
11218         if (!success)
11219             return false;
11220 
11221         // base = if n == 15 then Align(PC,4) else R[n];
11222         uint32_t base;
11223         if (n == 15)
11224             base = AlignPC (Rn);
11225         else
11226             base = Rn;
11227 
11228         // address = if add then (base + imm32) else (base - imm32);
11229         addr_t address;
11230         if (add)
11231             address = base + imm32;
11232         else
11233             address = base - imm32;
11234 
11235         const uint32_t addr_byte_size = GetAddressByteSize();
11236         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11237 
11238         EmulateInstruction::Context context;
11239         context.type = eContextRegisterLoad;
11240         context.SetRegisterPlusOffset (base_reg, address - base);
11241 
11242         if (single_reg)
11243         {
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, data))
11250                 return false;
11251         }
11252         else
11253         {
11254             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11255             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11256             if (!success)
11257                 return false;
11258 
11259             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11260             uint32_t word2 = 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 endianness.
11264             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11265             uint64_t data64;
11266             if (GetByteOrder() == eByteOrderBig)
11267             {
11268                 data64 = word1;
11269                 data64 = (data64 << 32) | word2;
11270             }
11271             else
11272             {
11273                 data64 = word2;
11274                 data64 = (data64 << 32) | word1;
11275             }
11276 
11277             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11278                 return false;
11279         }
11280     }
11281     return true;
11282 }
11283 
11284 // A8.6.400 VSTR
11285 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11286 // optional offset.
11287 bool
11288 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11289 {
11290 #if 0
11291     if ConditionPassed() then
11292         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11293         address = if add then (R[n] + imm32) else (R[n] - imm32);
11294         if single_reg then
11295             MemA[address,4] = S[d];
11296         else
11297             // Store as two word-aligned words in the correct order for current endianness.
11298             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11299             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11300 #endif
11301 
11302     bool success = false;
11303 
11304     if (ConditionPassed (opcode))
11305     {
11306         bool single_reg;
11307         bool add;
11308         uint32_t imm32;
11309         uint32_t d;
11310         uint32_t n;
11311 
11312         switch (encoding)
11313         {
11314             case eEncodingT1:
11315             case eEncodingA1:
11316                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11317                 single_reg = false;
11318                 add = BitIsSet (opcode, 23);
11319                 imm32 = Bits32 (opcode, 7, 0) << 2;
11320 
11321                 // d = UInt(D:Vd); n = UInt(Rn);
11322                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11323                 n = Bits32 (opcode, 19, 16);
11324 
11325                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11326                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11327                     return false;
11328 
11329                 break;
11330 
11331             case eEncodingT2:
11332             case eEncodingA2:
11333                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11334                 single_reg = true;
11335                 add = BitIsSet (opcode, 23);
11336                 imm32 = Bits32 (opcode, 7, 0) << 2;
11337 
11338                 // d = UInt(Vd:D); n = UInt(Rn);
11339                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11340                 n = Bits32 (opcode, 19, 16);
11341 
11342                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11343                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11344                     return false;
11345 
11346                 break;
11347 
11348             default:
11349                 return false;
11350         }
11351 
11352         RegisterInfo base_reg;
11353         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11354 
11355         uint32_t Rn = ReadCoreReg (n, &success);
11356         if (!success)
11357             return false;
11358 
11359         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11360         addr_t address;
11361         if (add)
11362             address = Rn + imm32;
11363         else
11364             address = Rn - imm32;
11365 
11366         const uint32_t addr_byte_size = GetAddressByteSize();
11367         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11368 
11369         RegisterInfo data_reg;
11370         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11371         EmulateInstruction::Context context;
11372         context.type = eContextRegisterStore;
11373         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11374 
11375         if (single_reg)
11376         {
11377             // MemA[address,4] = S[d];
11378             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11379             if (!success)
11380                 return false;
11381 
11382             if (!MemAWrite (context, address, data, addr_byte_size))
11383                 return false;
11384         }
11385         else
11386         {
11387             // // Store as two word-aligned words in the correct order for current endianness.
11388             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11389             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11390             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11391             if (!success)
11392                 return false;
11393 
11394             if (GetByteOrder() == eByteOrderBig)
11395             {
11396                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11397                     return false;
11398 
11399                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11400                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11401                     return false;
11402             }
11403             else
11404             {
11405                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11406                     return false;
11407 
11408                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11409                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11410                     return false;
11411             }
11412         }
11413     }
11414     return true;
11415 }
11416 
11417 // A8.6.307 VLDI1 (multiple single elements)
11418 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11419 // element of each register is loaded.
11420 bool
11421 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11422 {
11423 #if 0
11424     if ConditionPassed() then
11425         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11426         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11427         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11428         for r = 0 to regs-1
11429             for e = 0 to elements-1
11430                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11431                 address = address + ebytes;
11432 #endif
11433 
11434     bool success = false;
11435 
11436     if (ConditionPassed (opcode))
11437     {
11438         uint32_t regs;
11439         uint32_t alignment;
11440         uint32_t ebytes;
11441         uint32_t esize;
11442         uint32_t elements;
11443         uint32_t d;
11444         uint32_t n;
11445         uint32_t m;
11446         bool wback;
11447         bool register_index;
11448 
11449         switch (encoding)
11450         {
11451             case eEncodingT1:
11452             case eEncodingA1:
11453             {
11454                 // case type of
11455                     // when '0111'
11456                         // regs = 1; if align<1> == '1' then UNDEFINED;
11457                     // when '1010'
11458                         // regs = 2; if align == '11' then UNDEFINED;
11459                     // when '0110'
11460                         // regs = 3; if align<1> == '1' then UNDEFINED;
11461                     // when '0010'
11462                         // regs = 4;
11463                     // otherwise
11464                         // SEE 'Related encodings';
11465                 uint32_t type = Bits32 (opcode, 11, 8);
11466                 uint32_t align = Bits32 (opcode, 5, 4);
11467                 if (type == 7) // '0111'
11468                 {
11469                     regs = 1;
11470                     if (BitIsSet (align, 1))
11471                         return false;
11472                 }
11473                 else if (type == 10) // '1010'
11474                 {
11475                     regs = 2;
11476                     if (align == 3)
11477                         return false;
11478 
11479                 }
11480                 else if (type == 6) // '0110'
11481                 {
11482                     regs = 3;
11483                     if (BitIsSet (align, 1))
11484                         return false;
11485                 }
11486                 else if (type == 2) // '0010'
11487                 {
11488                     regs = 4;
11489                 }
11490                 else
11491                     return false;
11492 
11493                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11494                 if (align == 0)
11495                     alignment = 1;
11496                 else
11497                     alignment = 4 << align;
11498 
11499                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11500                 ebytes = 1 << Bits32 (opcode, 7, 6);
11501                 esize = 8 * ebytes;
11502                 elements = 8 / ebytes;
11503 
11504                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11505                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11506                 n = Bits32 (opcode, 19, 15);
11507                 m = Bits32 (opcode, 3, 0);
11508 
11509                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11510                 wback = (m != 15);
11511                 register_index = ((m != 15) && (m != 13));
11512 
11513                 // if d+regs > 32 then UNPREDICTABLE;
11514                 if ((d + regs) > 32)
11515                     return false;
11516             }
11517                 break;
11518 
11519             default:
11520                 return false;
11521         }
11522 
11523         RegisterInfo base_reg;
11524         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11525 
11526         uint32_t Rn = ReadCoreReg (n, &success);
11527         if (!success)
11528             return false;
11529 
11530         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11531         addr_t address = Rn;
11532         if ((address % alignment) != 0)
11533             return false;
11534 
11535         EmulateInstruction::Context context;
11536         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11537         if (wback)
11538         {
11539             uint32_t Rm = ReadCoreReg (m, &success);
11540             if (!success)
11541                 return false;
11542 
11543             uint32_t offset;
11544             if (register_index)
11545                 offset = Rm;
11546             else
11547                 offset = 8 * regs;
11548 
11549             uint32_t value = Rn + offset;
11550             context.type = eContextAdjustBaseRegister;
11551             context.SetRegisterPlusOffset (base_reg, offset);
11552 
11553             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11554                 return false;
11555 
11556         }
11557 
11558         // for r = 0 to regs-1
11559         for (uint32_t r = 0; r < regs; ++r)
11560         {
11561             // for e = 0 to elements-1
11562             uint64_t assembled_data = 0;
11563             for (uint32_t e = 0; e < elements; ++e)
11564             {
11565                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11566                 context.type = eContextRegisterLoad;
11567                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11568                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11569                 if (!success)
11570                     return false;
11571 
11572                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11573 
11574                 // address = address + ebytes;
11575                 address = address + ebytes;
11576             }
11577             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11578                 return false;
11579         }
11580     }
11581     return true;
11582 }
11583 
11584 // A8.6.308 VLD1 (single element to one lane)
11585 //
11586 bool
11587 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11588 {
11589 #if 0
11590     if ConditionPassed() then
11591         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11592         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11593         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11594         Elem[D[d],index,esize] = MemU[address,ebytes];
11595 #endif
11596 
11597     bool success = false;
11598 
11599     if (ConditionPassed (opcode))
11600     {
11601         uint32_t ebytes;
11602         uint32_t esize;
11603         uint32_t index;
11604         uint32_t alignment;
11605         uint32_t d;
11606         uint32_t n;
11607         uint32_t m;
11608         bool wback;
11609         bool register_index;
11610 
11611         switch (encoding)
11612         {
11613             case eEncodingT1:
11614             case eEncodingA1:
11615             {
11616                 uint32_t size = Bits32 (opcode, 11, 10);
11617                 uint32_t index_align = Bits32 (opcode, 7, 4);
11618                 // if size == '11' then SEE VLD1 (single element to all lanes);
11619                 if (size == 3)
11620                    return EmulateVLD1SingleAll (opcode, encoding);
11621                 // case size of
11622                 if (size == 0) // when '00'
11623                 {
11624                     // if index_align<0> != '0' then UNDEFINED;
11625                     if (BitIsClear (index_align, 0))
11626                         return false;
11627 
11628                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11629                     ebytes = 1;
11630                     esize = 8;
11631                     index = Bits32 (index_align, 3, 1);
11632                     alignment = 1;
11633                 }
11634                 else if (size == 1) // when '01'
11635                 {
11636                     // if index_align<1> != '0' then UNDEFINED;
11637                     if (BitIsClear (index_align, 1))
11638                         return false;
11639 
11640                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11641                     ebytes = 2;
11642                     esize = 16;
11643                     index = Bits32 (index_align, 3, 2);
11644 
11645                     // alignment = if index_align<0> == '0' then 1 else 2;
11646                     if (BitIsClear (index_align, 0))
11647                         alignment = 1;
11648                     else
11649                         alignment = 2;
11650                 }
11651                 else if (size == 2) // when '10'
11652                 {
11653                     // if index_align<2> != '0' then UNDEFINED;
11654                     if (BitIsClear (index_align, 2))
11655                         return false;
11656 
11657                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11658                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11659                         return false;
11660 
11661                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11662                     ebytes = 4;
11663                     esize = 32;
11664                     index = Bit32 (index_align, 3);
11665 
11666                     // alignment = if index_align<1:0> == '00' then 1 else 4;
11667                     if (Bits32 (index_align, 1, 0) == 0)
11668                         alignment = 1;
11669                     else
11670                         alignment = 4;
11671                 }
11672                 else
11673                 {
11674                     return false;
11675                 }
11676                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11677                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11678                 n = Bits32 (opcode, 19, 16);
11679                 m = Bits32 (opcode, 3, 0);
11680 
11681                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11682                 wback = (m != 15);
11683                 register_index = ((m != 15) && (m != 13));
11684 
11685                 if (n == 15)
11686                     return false;
11687 
11688             }
11689                 break;
11690 
11691             default:
11692                 return false;
11693         }
11694 
11695         RegisterInfo base_reg;
11696         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11697 
11698         uint32_t Rn = ReadCoreReg (n, &success);
11699         if (!success)
11700             return false;
11701 
11702         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11703         addr_t address = Rn;
11704         if ((address % alignment) != 0)
11705             return false;
11706 
11707         EmulateInstruction::Context context;
11708         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11709         if (wback)
11710         {
11711             uint32_t Rm = ReadCoreReg (m, &success);
11712             if (!success)
11713                 return false;
11714 
11715             uint32_t offset;
11716             if (register_index)
11717                 offset = Rm;
11718             else
11719                 offset = ebytes;
11720 
11721             uint32_t value = Rn + offset;
11722 
11723             context.type = eContextAdjustBaseRegister;
11724             context.SetRegisterPlusOffset (base_reg, offset);
11725 
11726             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11727                 return false;
11728         }
11729 
11730         // Elem[D[d],index,esize] = MemU[address,ebytes];
11731         uint32_t element = MemURead (context, address, esize, 0, &success);
11732         if (!success)
11733             return false;
11734 
11735         element = element << (index * esize);
11736 
11737         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11738         if (!success)
11739             return false;
11740 
11741         uint64_t all_ones = -1;
11742         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11743                                                           // at element & to the right of element.
11744         if (index > 0)
11745             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11746                                                                      // now mask should be 0's where element goes & 1's
11747                                                                      // everywhere else.
11748 
11749         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11750         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11751 
11752         context.type = eContextRegisterLoad;
11753         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11754             return false;
11755     }
11756     return true;
11757 }
11758 
11759 // A8.6.391 VST1 (multiple single elements)
11760 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11761 // interleaving.  Every element of each register is stored.
11762 bool
11763 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11764 {
11765 #if 0
11766     if ConditionPassed() then
11767         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11768         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11769         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11770         for r = 0 to regs-1
11771             for e = 0 to elements-1
11772                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11773                 address = address + ebytes;
11774 #endif
11775 
11776     bool success = false;
11777 
11778     if (ConditionPassed (opcode))
11779     {
11780         uint32_t regs;
11781         uint32_t alignment;
11782         uint32_t ebytes;
11783         uint32_t esize;
11784         uint32_t elements;
11785         uint32_t d;
11786         uint32_t n;
11787         uint32_t m;
11788         bool wback;
11789         bool register_index;
11790 
11791         switch (encoding)
11792         {
11793             case eEncodingT1:
11794             case eEncodingA1:
11795             {
11796                 uint32_t type = Bits32 (opcode, 11, 8);
11797                 uint32_t align = Bits32 (opcode, 5, 4);
11798 
11799                 // case type of
11800                 if (type == 7)    // when '0111'
11801                 {
11802                     // regs = 1; if align<1> == '1' then UNDEFINED;
11803                     regs = 1;
11804                     if (BitIsSet (align, 1))
11805                         return false;
11806                 }
11807                 else if (type == 10) // when '1010'
11808                 {
11809                     // regs = 2; if align == '11' then UNDEFINED;
11810                     regs = 2;
11811                     if (align == 3)
11812                         return false;
11813                 }
11814                 else if (type == 6) // when '0110'
11815                 {
11816                     // regs = 3; if align<1> == '1' then UNDEFINED;
11817                     regs = 3;
11818                     if (BitIsSet (align, 1))
11819                         return false;
11820                 }
11821                 else if (type == 2) // when '0010'
11822                     // regs = 4;
11823                     regs = 4;
11824                 else // otherwise
11825                     // SEE 'Related encodings';
11826                     return false;
11827 
11828                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11829                 if (align == 0)
11830                     alignment = 1;
11831                 else
11832                     alignment = 4 << align;
11833 
11834                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11835                 ebytes = 1 << Bits32 (opcode,7, 6);
11836                 esize = 8 * ebytes;
11837                 elements = 8 / ebytes;
11838 
11839                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11840                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11841                 n = Bits32 (opcode, 19, 16);
11842                 m = Bits32 (opcode, 3, 0);
11843 
11844                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11845                 wback = (m != 15);
11846                 register_index = ((m != 15) && (m != 13));
11847 
11848                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11849                 if ((d + regs) > 32)
11850                     return false;
11851 
11852                 if (n == 15)
11853                     return false;
11854 
11855             }
11856                 break;
11857 
11858             default:
11859                 return false;
11860         }
11861 
11862         RegisterInfo base_reg;
11863         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11864 
11865         uint32_t Rn = ReadCoreReg (n, &success);
11866         if (!success)
11867             return false;
11868 
11869         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11870         addr_t address = Rn;
11871         if ((address % alignment) != 0)
11872             return false;
11873 
11874         EmulateInstruction::Context context;
11875         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11876         if (wback)
11877         {
11878             uint32_t Rm = ReadCoreReg (m, &success);
11879             if (!success)
11880                 return false;
11881 
11882             uint32_t offset;
11883             if (register_index)
11884                 offset = Rm;
11885             else
11886                 offset = 8 * regs;
11887 
11888             context.type = eContextAdjustBaseRegister;
11889             context.SetRegisterPlusOffset (base_reg, offset);
11890 
11891             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11892                 return false;
11893         }
11894 
11895         RegisterInfo data_reg;
11896         context.type = eContextRegisterStore;
11897         // for r = 0 to regs-1
11898         for (uint32_t r = 0; r < regs; ++r)
11899         {
11900             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11901             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11902             if (!success)
11903                 return false;
11904 
11905              // for e = 0 to elements-1
11906             for (uint32_t e = 0; e < elements; ++e)
11907             {
11908                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11909                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11910 
11911                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11912                 if (!MemUWrite (context, address, word, ebytes))
11913                     return false;
11914 
11915                 // address = address + ebytes;
11916                 address = address + ebytes;
11917             }
11918         }
11919     }
11920     return true;
11921 }
11922 
11923 // A8.6.392 VST1 (single element from one lane)
11924 // This instruction stores one element to memory from one element of a register.
11925 bool
11926 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11927 {
11928 #if 0
11929     if ConditionPassed() then
11930         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11931         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11932         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11933         MemU[address,ebytes] = Elem[D[d],index,esize];
11934 #endif
11935 
11936     bool success = false;
11937 
11938     if (ConditionPassed (opcode))
11939     {
11940         uint32_t ebytes;
11941         uint32_t esize;
11942         uint32_t index;
11943         uint32_t alignment;
11944         uint32_t d;
11945         uint32_t n;
11946         uint32_t m;
11947         bool wback;
11948         bool register_index;
11949 
11950         switch (encoding)
11951         {
11952             case eEncodingT1:
11953             case eEncodingA1:
11954             {
11955                 uint32_t size = Bits32 (opcode, 11, 10);
11956                 uint32_t index_align = Bits32 (opcode, 7, 4);
11957 
11958                 // if size == '11' then UNDEFINED;
11959                 if (size == 3)
11960                     return false;
11961 
11962                 // case size of
11963                 if (size == 0) // when '00'
11964                 {
11965                     // if index_align<0> != '0' then UNDEFINED;
11966                     if (BitIsClear (index_align, 0))
11967                         return false;
11968                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11969                     ebytes = 1;
11970                     esize = 8;
11971                     index = Bits32 (index_align, 3, 1);
11972                     alignment = 1;
11973                 }
11974                 else if (size == 1) // when '01'
11975                 {
11976                     // if index_align<1> != '0' then UNDEFINED;
11977                     if (BitIsClear (index_align, 1))
11978                         return false;
11979 
11980                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11981                     ebytes = 2;
11982                     esize = 16;
11983                     index = Bits32 (index_align, 3, 2);
11984 
11985                     // alignment = if index_align<0> == '0' then 1 else 2;
11986                     if (BitIsClear (index_align, 0))
11987                         alignment = 1;
11988                     else
11989                         alignment = 2;
11990                 }
11991                 else if (size == 2) // when '10'
11992                 {
11993                     // if index_align<2> != '0' then UNDEFINED;
11994                     if (BitIsClear (index_align, 2))
11995                         return false;
11996 
11997                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11998                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11999                         return false;
12000 
12001                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12002                     ebytes = 4;
12003                     esize = 32;
12004                     index = Bit32 (index_align, 3);
12005 
12006                     // alignment = if index_align<1:0> == '00' then 1 else 4;
12007                     if (Bits32 (index_align, 1, 0) == 0)
12008                         alignment = 1;
12009                     else
12010                         alignment = 4;
12011                 }
12012                 else
12013                 {
12014                     return false;
12015                 }
12016                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12017                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12018                 n = Bits32 (opcode, 19, 16);
12019                 m = Bits32 (opcode, 3, 0);
12020 
12021                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
12022                 wback = (m != 15);
12023                 register_index = ((m != 15) && (m != 13));
12024 
12025                 if (n == 15)
12026                     return false;
12027             }
12028                 break;
12029 
12030             default:
12031                 return false;
12032         }
12033 
12034         RegisterInfo base_reg;
12035         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12036 
12037         uint32_t Rn = ReadCoreReg (n, &success);
12038         if (!success)
12039             return false;
12040 
12041         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12042         addr_t address = Rn;
12043         if ((address % alignment) != 0)
12044             return false;
12045 
12046         EmulateInstruction::Context context;
12047         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12048         if (wback)
12049         {
12050             uint32_t Rm = ReadCoreReg (m, &success);
12051             if (!success)
12052                 return false;
12053 
12054             uint32_t offset;
12055             if (register_index)
12056                 offset = Rm;
12057             else
12058                 offset = ebytes;
12059 
12060             context.type = eContextAdjustBaseRegister;
12061             context.SetRegisterPlusOffset (base_reg, offset);
12062 
12063             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12064                 return false;
12065         }
12066 
12067         // MemU[address,ebytes] = Elem[D[d],index,esize];
12068         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12069         if (!success)
12070             return false;
12071 
12072         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
12073 
12074         RegisterInfo data_reg;
12075         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12076         context.type = eContextRegisterStore;
12077         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
12078 
12079         if (!MemUWrite (context, address, word, ebytes))
12080             return false;
12081     }
12082     return true;
12083 }
12084 
12085 // A8.6.309 VLD1 (single element to all lanes)
12086 // This instruction loads one element from memory into every element of one or two vectors.
12087 bool
12088 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
12089 {
12090 #if 0
12091     if ConditionPassed() then
12092         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12093         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12094         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12095         replicated_element = Replicate(MemU[address,ebytes], elements);
12096         for r = 0 to regs-1
12097             D[d+r] = replicated_element;
12098 #endif
12099 
12100     bool success = false;
12101 
12102     if (ConditionPassed (opcode))
12103     {
12104         uint32_t ebytes;
12105         uint32_t elements;
12106         uint32_t regs;
12107         uint32_t alignment;
12108         uint32_t d;
12109         uint32_t n;
12110         uint32_t m;
12111         bool wback;
12112         bool register_index;
12113 
12114         switch (encoding)
12115         {
12116             case eEncodingT1:
12117             case eEncodingA1:
12118             {
12119                 //if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12120                 uint32_t size = Bits32 (opcode, 7, 6);
12121                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12122                     return false;
12123 
12124                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2;
12125                 ebytes = 1 << size;
12126                 elements = 8 / ebytes;
12127                 if (BitIsClear (opcode, 5))
12128                     regs = 1;
12129                 else
12130                     regs = 2;
12131 
12132                 //alignment = if a == '0' then 1 else ebytes;
12133                 if (BitIsClear (opcode, 4))
12134                     alignment = 1;
12135                 else
12136                     alignment = ebytes;
12137 
12138                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12139                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12140                 n = Bits32 (opcode, 19, 16);
12141                 m = Bits32 (opcode, 3, 0);
12142 
12143                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12144                 wback = (m != 15);
12145                 register_index = ((m != 15) && (m != 13));
12146 
12147                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12148                 if ((d + regs) > 32)
12149                     return false;
12150 
12151                 if (n == 15)
12152                     return false;
12153             }
12154             break;
12155 
12156             default:
12157                 return false;
12158         }
12159 
12160         RegisterInfo base_reg;
12161         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12162 
12163         uint32_t Rn = ReadCoreReg (n, &success);
12164         if (!success)
12165             return false;
12166 
12167         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12168         addr_t address = Rn;
12169         if ((address % alignment) != 0)
12170             return false;
12171 
12172         EmulateInstruction::Context context;
12173         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12174         if (wback)
12175         {
12176             uint32_t Rm = ReadCoreReg (m, &success);
12177             if (!success)
12178                 return false;
12179 
12180             uint32_t offset;
12181             if (register_index)
12182                 offset = Rm;
12183             else
12184                 offset = ebytes;
12185 
12186             context.type = eContextAdjustBaseRegister;
12187             context.SetRegisterPlusOffset (base_reg, offset);
12188 
12189             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12190                 return false;
12191         }
12192 
12193         // replicated_element = Replicate(MemU[address,ebytes], elements);
12194 
12195         context.type = eContextRegisterLoad;
12196         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12197         if (!success)
12198             return false;
12199 
12200         uint64_t replicated_element = 0;
12201         uint32_t esize = ebytes * 8;
12202         for (uint32_t e = 0; e < elements; ++e)
12203             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12204 
12205         // for r = 0 to regs-1
12206         for (uint32_t r = 0; r < regs; ++r)
12207         {
12208             // D[d+r] = replicated_element;
12209             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12210                 return false;
12211         }
12212     }
12213     return true;
12214 }
12215 
12216 // B6.2.13 SUBS PC, LR and related instructions
12217 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12218 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12219 bool
12220 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12221 {
12222 #if 0
12223     if ConditionPassed() then
12224         EncodingSpecificOperations();
12225         if CurrentInstrSet() == InstrSet_ThumbEE then
12226             UNPREDICTABLE;
12227         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12228         case opcode of
12229             when '0000' result = R[n] AND operand2; // AND
12230             when '0001' result = R[n] EOR operand2; // EOR
12231             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12232             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12233             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12234             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12235             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12236             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12237             when '1100' result = R[n] OR operand2; // ORR
12238             when '1101' result = operand2; // MOV
12239             when '1110' result = R[n] AND NOT(operand2); // BIC
12240             when '1111' result = NOT(operand2); // MVN
12241         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12242         BranchWritePC(result);
12243 #endif
12244 
12245     bool success = false;
12246 
12247     if (ConditionPassed (opcode))
12248     {
12249         uint32_t n;
12250         uint32_t m;
12251         uint32_t imm32;
12252         bool register_form;
12253         ARM_ShifterType shift_t;
12254         uint32_t shift_n;
12255         uint32_t code;
12256 
12257         switch (encoding)
12258         {
12259             case eEncodingT1:
12260                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12261                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB
12262                 n = 14;
12263                 imm32 = Bits32 (opcode, 7, 0);
12264                 register_form = false;
12265                 code = 2;
12266 
12267                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12268                 if (InITBlock() && !LastInITBlock())
12269                     return false;
12270 
12271                 break;
12272 
12273             case eEncodingA1:
12274                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12275                 n = Bits32 (opcode, 19, 16);
12276                 imm32 = ARMExpandImm (opcode);
12277                 register_form = false;
12278                 code = Bits32 (opcode, 24, 21);
12279 
12280                 break;
12281 
12282             case eEncodingA2:
12283                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12284                 n = Bits32 (opcode, 19, 16);
12285                 m = Bits32 (opcode, 3, 0);
12286                 register_form = true;
12287 
12288                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12289                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12290 
12291                 break;
12292 
12293             default:
12294                 return false;
12295         }
12296 
12297         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12298         uint32_t operand2;
12299         if (register_form)
12300         {
12301             uint32_t Rm = ReadCoreReg (m, &success);
12302             if (!success)
12303                 return false;
12304 
12305             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12306             if (!success)
12307                 return false;
12308         }
12309         else
12310         {
12311             operand2 = imm32;
12312         }
12313 
12314         uint32_t Rn = ReadCoreReg (n, &success);
12315         if (!success)
12316             return false;
12317 
12318         AddWithCarryResult result;
12319 
12320         // case opcode of
12321         switch (code)
12322         {
12323             case 0: // when '0000'
12324                 // result = R[n] AND operand2; // AND
12325                 result.result = Rn & operand2;
12326                 break;
12327 
12328             case 1: // when '0001'
12329                 // result = R[n] EOR operand2; // EOR
12330                 result.result = Rn ^ operand2;
12331                 break;
12332 
12333             case 2: // when '0010'
12334                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12335                 result = AddWithCarry (Rn, ~(operand2), 1);
12336                 break;
12337 
12338             case 3: // when '0011'
12339                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12340                 result = AddWithCarry (~(Rn), operand2, 1);
12341                 break;
12342 
12343             case 4: // when '0100'
12344                 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12345                 result = AddWithCarry (Rn, operand2, 0);
12346                 break;
12347 
12348             case 5: // when '0101'
12349                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12350                 result = AddWithCarry (Rn, operand2, APSR_C);
12351                 break;
12352 
12353             case 6: // when '0110'
12354                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12355                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12356                 break;
12357 
12358             case 7: // when '0111'
12359                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12360                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12361                 break;
12362 
12363             case 10: // when '1100'
12364                 // result = R[n] OR operand2; // ORR
12365                 result.result = Rn | operand2;
12366                 break;
12367 
12368             case 11: // when '1101'
12369                 // result = operand2; // MOV
12370                 result.result = operand2;
12371                 break;
12372 
12373             case 12: // when '1110'
12374                 // result = R[n] AND NOT(operand2); // BIC
12375                 result.result = Rn & ~(operand2);
12376                 break;
12377 
12378             case 15: // when '1111'
12379                 // result = NOT(operand2); // MVN
12380                 result.result = ~(operand2);
12381                 break;
12382 
12383             default:
12384                 return false;
12385         }
12386         // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12387 
12388         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12389         // the best.
12390         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12391         if (!success)
12392             return false;
12393 
12394         CPSRWriteByInstr (spsr, 15, true);
12395 
12396         // BranchWritePC(result);
12397         EmulateInstruction::Context context;
12398         context.type = eContextAdjustPC;
12399         context.SetImmediate (result.result);
12400 
12401         BranchWritePC (context, result.result);
12402     }
12403     return true;
12404 }
12405 
12406 EmulateInstructionARM::ARMOpcode*
12407 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12408 {
12409     static ARMOpcode
12410     g_arm_opcodes[] =
12411     {
12412         //----------------------------------------------------------------------
12413         // Prologue instructions
12414         //----------------------------------------------------------------------
12415 
12416         // push register(s)
12417         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12418         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12419 
12420         // set r7 to point to a stack offset
12421         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12422         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12423         // copy the stack pointer to ip
12424         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12425         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12426         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12427 
12428         // adjust the stack pointer
12429         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12430         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12431 
12432         // push one register
12433         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12434         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12435 
12436         // vector push consecutive extension register(s)
12437         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12438         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12439 
12440         //----------------------------------------------------------------------
12441         // Epilogue instructions
12442         //----------------------------------------------------------------------
12443 
12444         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12445         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12446         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12447         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12448 
12449         //----------------------------------------------------------------------
12450         // Supervisor Call (previously Software Interrupt)
12451         //----------------------------------------------------------------------
12452         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12453 
12454         //----------------------------------------------------------------------
12455         // Branch instructions
12456         //----------------------------------------------------------------------
12457         // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
12458         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12459         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12460         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12461         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12462         // for example, "bx lr"
12463         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12464         // bxj
12465         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12466 
12467         //----------------------------------------------------------------------
12468         // Data-processing instructions
12469         //----------------------------------------------------------------------
12470         // adc (immediate)
12471         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12472         // adc (register)
12473         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12474         // add (immediate)
12475         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12476         // add (register)
12477         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12478         // add (register-shifted register)
12479         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12480         // adr
12481         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12482         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12483         // and (immediate)
12484         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12485         // and (register)
12486         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12487         // bic (immediate)
12488         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12489         // bic (register)
12490         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12491         // eor (immediate)
12492         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12493         // eor (register)
12494         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12495         // orr (immediate)
12496         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12497         // orr (register)
12498         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12499         // rsb (immediate)
12500         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12501         // rsb (register)
12502         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12503         // rsc (immediate)
12504         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12505         // rsc (register)
12506         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12507         // sbc (immediate)
12508         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12509         // sbc (register)
12510         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12511         // sub (immediate, ARM)
12512         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12513         // sub (sp minus immediate)
12514         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12515         // sub (register)
12516         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12517         // teq (immediate)
12518         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12519         // teq (register)
12520         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12521         // tst (immediate)
12522         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12523         // tst (register)
12524         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12525 
12526         // mov (immediate)
12527         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12528         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12529         // mov (register)
12530         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12531         // mvn (immediate)
12532         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12533         // mvn (register)
12534         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12535         // cmn (immediate)
12536         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12537         // cmn (register)
12538         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12539         // cmp (immediate)
12540         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12541         // cmp (register)
12542         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12543         // asr (immediate)
12544         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12545         // asr (register)
12546         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12547         // lsl (immediate)
12548         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12549         // lsl (register)
12550         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12551         // lsr (immediate)
12552         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12553         // lsr (register)
12554         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12555         // rrx is a special case encoding of ror (immediate)
12556         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12557         // ror (immediate)
12558         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12559         // ror (register)
12560         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12561         // mul
12562         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12563 
12564         // subs pc, lr and related instructions
12565         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12566         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12567 
12568         //----------------------------------------------------------------------
12569         // Load instructions
12570         //----------------------------------------------------------------------
12571         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12572         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12573         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12574         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12575         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12576         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12577         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12578         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12579         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12580         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12581         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12582         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12583         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12584         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12585         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12586         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12587         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12588         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12589         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12590         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12591         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12592         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12593         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12594         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12595         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12596 
12597         //----------------------------------------------------------------------
12598         // Store instructions
12599         //----------------------------------------------------------------------
12600         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12601         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12602         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12603         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12604         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12605         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12606         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12607         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12608         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12609         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12610         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12611         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12612         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12613         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12614         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12615         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12616         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12617 
12618         //----------------------------------------------------------------------
12619         // Other instructions
12620         //----------------------------------------------------------------------
12621         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12622         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12623         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12624         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12625         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12626 
12627     };
12628     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12629 
12630     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12631     {
12632         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12633             (g_arm_opcodes[i].variants & arm_isa) != 0)
12634             return &g_arm_opcodes[i];
12635     }
12636     return NULL;
12637 }
12638 
12639 
12640 EmulateInstructionARM::ARMOpcode*
12641 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12642 {
12643 
12644     static ARMOpcode
12645     g_thumb_opcodes[] =
12646     {
12647         //----------------------------------------------------------------------
12648         // Prologue instructions
12649         //----------------------------------------------------------------------
12650 
12651         // push register(s)
12652         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12653         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12654         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12655 
12656         // set r7 to point to a stack offset
12657         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12658         // copy the stack pointer to r7
12659         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12660         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12661         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12662 
12663         // PC-relative load into register (see also EmulateADDSPRm)
12664         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12665 
12666         // adjust the stack pointer
12667         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12668         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12669         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12670         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12671         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12672 
12673         // vector push consecutive extension register(s)
12674         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12675         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12676 
12677         //----------------------------------------------------------------------
12678         // Epilogue instructions
12679         //----------------------------------------------------------------------
12680 
12681         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12682         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12683         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12684         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12685         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12686         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12687         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12688 
12689         //----------------------------------------------------------------------
12690         // Supervisor Call (previously Software Interrupt)
12691         //----------------------------------------------------------------------
12692         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12693 
12694         //----------------------------------------------------------------------
12695         // If Then makes up to four following instructions conditional.
12696         //----------------------------------------------------------------------
12697         // The next 5 opcode _must_ come before the if then instruction
12698         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12699         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12700         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12701         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12702         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12703         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12704 
12705         //----------------------------------------------------------------------
12706         // Branch instructions
12707         //----------------------------------------------------------------------
12708         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12709         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12710         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12711         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12712         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12713         // J1 == J2 == 1
12714         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12715         // J1 == J2 == 1
12716         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12717         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12718         // for example, "bx lr"
12719         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12720         // bxj
12721         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12722         // compare and branch
12723         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12724         // table branch byte
12725         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12726         // table branch halfword
12727         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12728 
12729         //----------------------------------------------------------------------
12730         // Data-processing instructions
12731         //----------------------------------------------------------------------
12732         // adc (immediate)
12733         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12734         // adc (register)
12735         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12736         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12737         // add (register)
12738         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12739         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12740         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12741         // adr
12742         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12743         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12744         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12745         // and (immediate)
12746         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12747         // and (register)
12748         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12749         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12750         // bic (immediate)
12751         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12752         // bic (register)
12753         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12754         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12755         // eor (immediate)
12756         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12757         // eor (register)
12758         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12759         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12760         // orr (immediate)
12761         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12762         // orr (register)
12763         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12764         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12765         // rsb (immediate)
12766         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12767         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12768         // rsb (register)
12769         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12770         // sbc (immediate)
12771         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12772         // sbc (register)
12773         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12774         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12775         // add (immediate, Thumb)
12776         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12777         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12778         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12779         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12780         // sub (immediate, Thumb)
12781         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12782         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12783         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12784         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12785         // sub (sp minus immediate)
12786         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12787         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12788         // sub (register)
12789         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12790         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12791         // teq (immediate)
12792         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12793         // teq (register)
12794         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12795         // tst (immediate)
12796         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12797         // tst (register)
12798         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12799         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12800 
12801 
12802         // move from high register to high register
12803         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12804         // move from low register to low register
12805         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12806         // mov{s}<c>.w <Rd>, <Rm>
12807         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12808         // move immediate
12809         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12810         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12811         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12812         // mvn (immediate)
12813         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12814         // mvn (register)
12815         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12816         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12817         // cmn (immediate)
12818         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12819         // cmn (register)
12820         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12821         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12822         // cmp (immediate)
12823         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12824         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12825         // cmp (register) (Rn and Rm both from r0-r7)
12826         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12827         // cmp (register) (Rn and Rm not both from r0-r7)
12828         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12829         { 0xfff08f00, 0xebb00f00, ARMvAll,       eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
12830         // asr (immediate)
12831         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12832         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12833         // asr (register)
12834         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12835         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12836         // lsl (immediate)
12837         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12838         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12839         // lsl (register)
12840         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12841         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12842         // lsr (immediate)
12843         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12844         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12845         // lsr (register)
12846         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12847         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12848         // rrx is a special case encoding of ror (immediate)
12849         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12850         // ror (immediate)
12851         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12852         // ror (register)
12853         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12854         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12855         // mul
12856         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12857         // mul
12858         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12859 
12860         // subs pc, lr and related instructions
12861         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12862 
12863         //----------------------------------------------------------------------
12864         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12865         // otherwise the wrong instructions will be selected.
12866         //----------------------------------------------------------------------
12867 
12868         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12869         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12870 
12871         //----------------------------------------------------------------------
12872         // Load instructions
12873         //----------------------------------------------------------------------
12874         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12875         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12876         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12877         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12878         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12879         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12880         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12881                   // Thumb2 PC-relative load into register
12882         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12883         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12884         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12885         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12886         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12887         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12888         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12889         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12890         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12891         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12892         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12893         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12894         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12895         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12896         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12897         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12898         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12899         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12900         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12901         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12902         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12903         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12904         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12905         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12906         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12907         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12908         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12909         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12910         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12911         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12912         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12913         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12914         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12915 
12916         //----------------------------------------------------------------------
12917         // Store instructions
12918         //----------------------------------------------------------------------
12919         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12920         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12921         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12922         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12923         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12924         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12925         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12926         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12927         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12928         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12929         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12930         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12931         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12932         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12933         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12934         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12935         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12936         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12937         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12938         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12939         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12940         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12941 
12942         //----------------------------------------------------------------------
12943         // Other instructions
12944         //----------------------------------------------------------------------
12945         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12946         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12947         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12948         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12949         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12950         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12951         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12952         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12953     };
12954 
12955     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12956     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12957     {
12958         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12959             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12960             return &g_thumb_opcodes[i];
12961     }
12962     return NULL;
12963 }
12964 
12965 bool
12966 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12967 {
12968     m_arch = arch;
12969     m_arm_isa = 0;
12970     const char *arch_cstr = arch.GetArchitectureName ();
12971     if (arch_cstr)
12972     {
12973         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12974         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12975         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12976         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12977         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12978         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12979         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12980         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12981         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12982         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12983         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12984         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12985         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12986     }
12987     return m_arm_isa != 0;
12988 }
12989 
12990 bool
12991 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12992 {
12993     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12994     {
12995         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12996             m_opcode_mode = eModeThumb;
12997         else
12998         {
12999             AddressClass addr_class = inst_addr.GetAddressClass();
13000 
13001             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
13002                 m_opcode_mode = eModeARM;
13003             else if (addr_class == eAddressClassCodeAlternateISA)
13004                 m_opcode_mode = eModeThumb;
13005             else
13006                 return false;
13007         }
13008         if (m_opcode_mode == eModeThumb)
13009             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13010         else
13011             m_opcode_cpsr = CPSR_MODE_USR;
13012         return true;
13013     }
13014     return false;
13015 }
13016 
13017 bool
13018 EmulateInstructionARM::ReadInstruction ()
13019 {
13020     bool success = false;
13021     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13022     if (success)
13023     {
13024         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
13025         if (success)
13026         {
13027             Context read_inst_context;
13028             read_inst_context.type = eContextReadOpcode;
13029             read_inst_context.SetNoArgs ();
13030 
13031             if (m_opcode_cpsr & MASK_CPSR_T)
13032             {
13033                 m_opcode_mode = eModeThumb;
13034                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13035 
13036                 if (success)
13037                 {
13038                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
13039                     {
13040                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
13041                     }
13042                     else
13043                     {
13044                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
13045                     }
13046                 }
13047             }
13048             else
13049             {
13050                 m_opcode_mode = eModeARM;
13051                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
13052             }
13053         }
13054     }
13055     if (!success)
13056     {
13057         m_opcode_mode = eModeInvalid;
13058         m_addr = LLDB_INVALID_ADDRESS;
13059     }
13060     return success;
13061 }
13062 
13063 uint32_t
13064 EmulateInstructionARM::ArchVersion ()
13065 {
13066     return m_arm_isa;
13067 }
13068 
13069 bool
13070 EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
13071 {
13072    // If we are ignoring conditions, then always return true.
13073    // this allows us to iterate over disassembly code and still
13074    // emulate an instruction even if we don't have all the right
13075    // bits set in the CPSR register...
13076     if (m_ignore_conditions)
13077         return true;
13078 
13079     const uint32_t cond = CurrentCond (opcode);
13080     if (cond == UINT32_MAX)
13081         return false;
13082 
13083     bool result = false;
13084     switch (UnsignedBits(cond, 3, 1))
13085     {
13086     case 0:
13087 		if (m_opcode_cpsr == 0)
13088 			result = true;
13089         else
13090             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13091 		break;
13092     case 1:
13093         if (m_opcode_cpsr == 0)
13094             result = true;
13095         else
13096             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13097 		break;
13098     case 2:
13099         if (m_opcode_cpsr == 0)
13100             result = true;
13101         else
13102             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13103 		break;
13104     case 3:
13105         if (m_opcode_cpsr == 0)
13106             result = true;
13107         else
13108             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13109 		break;
13110     case 4:
13111         if (m_opcode_cpsr == 0)
13112             result = true;
13113         else
13114             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13115 		break;
13116     case 5:
13117         if (m_opcode_cpsr == 0)
13118             result = true;
13119         else
13120 		{
13121             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13122             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13123             result = n == v;
13124         }
13125         break;
13126     case 6:
13127         if (m_opcode_cpsr == 0)
13128             result = true;
13129         else
13130 		{
13131             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13132             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13133             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13134         }
13135         break;
13136     case 7:
13137         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13138         // opcodes different meanings, but always means execution happens.
13139         return true;
13140     }
13141 
13142     if (cond & 1)
13143         result = !result;
13144     return result;
13145 }
13146 
13147 uint32_t
13148 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13149 {
13150     switch (m_opcode_mode)
13151     {
13152     case eModeInvalid:
13153         break;
13154 
13155     case eModeARM:
13156         return UnsignedBits(opcode, 31, 28);
13157 
13158     case eModeThumb:
13159         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13160         // 'cond' field of the encoding.
13161         {
13162             const uint32_t byte_size = m_opcode.GetByteSize();
13163             if (byte_size == 2)
13164             {
13165                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13166                     return Bits32(opcode, 11, 8);
13167             }
13168             else if (byte_size == 4)
13169             {
13170                 if (Bits32(opcode, 31, 27) == 0x1e &&
13171                     Bits32(opcode, 15, 14) == 0x02 &&
13172                     Bits32(opcode, 12, 12) == 0x00 &&
13173                     Bits32(opcode, 25, 22) <= 0x0d)
13174                 {
13175                     return Bits32(opcode, 25, 22);
13176                 }
13177             }
13178             else
13179                 // We have an invalid thumb instruction, let's bail out.
13180                 break;
13181 
13182             return m_it_session.GetCond();
13183         }
13184     }
13185     return UINT32_MAX;  // Return invalid value
13186 }
13187 
13188 bool
13189 EmulateInstructionARM::InITBlock()
13190 {
13191     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13192 }
13193 
13194 bool
13195 EmulateInstructionARM::LastInITBlock()
13196 {
13197     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13198 }
13199 
13200 bool
13201 EmulateInstructionARM::BadMode (uint32_t mode)
13202 {
13203 
13204     switch (mode)
13205     {
13206         case 16: return false; // '10000'
13207         case 17: return false; // '10001'
13208         case 18: return false; // '10010'
13209         case 19: return false; // '10011'
13210         case 22: return false; // '10110'
13211         case 23: return false; // '10111'
13212         case 27: return false; // '11011'
13213         case 31: return false; // '11111'
13214         default: return true;
13215     }
13216     return true;
13217 }
13218 
13219 bool
13220 EmulateInstructionARM::CurrentModeIsPrivileged ()
13221 {
13222     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13223 
13224     if (BadMode (mode))
13225         return false;
13226 
13227     if (mode == 16)
13228         return false;
13229 
13230     return true;
13231 }
13232 
13233 void
13234 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13235 {
13236     bool privileged = CurrentModeIsPrivileged();
13237 
13238     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13239 
13240     if (BitIsSet (bytemask, 3))
13241     {
13242         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13243         if (affect_execstate)
13244             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13245     }
13246 
13247     if (BitIsSet (bytemask, 2))
13248     {
13249         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13250     }
13251 
13252     if (BitIsSet (bytemask, 1))
13253     {
13254         if (affect_execstate)
13255             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13256         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13257         if (privileged)
13258             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13259     }
13260 
13261     if (BitIsSet (bytemask, 0))
13262     {
13263         if (privileged)
13264             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13265         if (affect_execstate)
13266             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13267         if (privileged)
13268             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13269     }
13270 
13271     m_opcode_cpsr = tmp_cpsr;
13272 }
13273 
13274 
13275 bool
13276 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13277 {
13278     addr_t target;
13279 
13280     // Check the current instruction set.
13281     if (CurrentInstrSet() == eModeARM)
13282         target = addr & 0xfffffffc;
13283     else
13284         target = addr & 0xfffffffe;
13285 
13286     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13287         return false;
13288 
13289     return true;
13290 }
13291 
13292 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13293 bool
13294 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13295 {
13296     addr_t target;
13297     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13298     // we want to record it and issue a WriteRegister callback so the clients
13299     // can track the mode changes accordingly.
13300     bool cpsr_changed = false;
13301 
13302     if (BitIsSet(addr, 0))
13303     {
13304         if (CurrentInstrSet() != eModeThumb)
13305         {
13306             SelectInstrSet(eModeThumb);
13307             cpsr_changed = true;
13308         }
13309         target = addr & 0xfffffffe;
13310         context.SetISA (eModeThumb);
13311     }
13312     else if (BitIsClear(addr, 1))
13313     {
13314         if (CurrentInstrSet() != eModeARM)
13315         {
13316             SelectInstrSet(eModeARM);
13317             cpsr_changed = true;
13318         }
13319         target = addr & 0xfffffffc;
13320         context.SetISA (eModeARM);
13321     }
13322     else
13323         return false; // address<1:0> == '10' => UNPREDICTABLE
13324 
13325     if (cpsr_changed)
13326     {
13327         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13328             return false;
13329     }
13330     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13331         return false;
13332 
13333     return true;
13334 }
13335 
13336 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13337 bool
13338 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13339 {
13340     if (ArchVersion() >= ARMv5T)
13341         return BXWritePC(context, addr);
13342     else
13343         return BranchWritePC((const Context)context, addr);
13344 }
13345 
13346 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13347 bool
13348 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13349 {
13350     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13351         return BXWritePC(context, addr);
13352     else
13353         return BranchWritePC((const Context)context, addr);
13354 }
13355 
13356 EmulateInstructionARM::Mode
13357 EmulateInstructionARM::CurrentInstrSet ()
13358 {
13359     return m_opcode_mode;
13360 }
13361 
13362 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13363 // ReadInstruction() is performed.  This function has a side effect of updating
13364 // the m_new_inst_cpsr member variable if necessary.
13365 bool
13366 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13367 {
13368     m_new_inst_cpsr = m_opcode_cpsr;
13369     switch (arm_or_thumb)
13370     {
13371     default:
13372         return false;
13373     case eModeARM:
13374         // Clear the T bit.
13375         m_new_inst_cpsr &= ~MASK_CPSR_T;
13376         break;
13377     case eModeThumb:
13378         // Set the T bit.
13379         m_new_inst_cpsr |= MASK_CPSR_T;
13380         break;
13381     }
13382     return true;
13383 }
13384 
13385 // This function returns TRUE if the processor currently provides support for
13386 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13387 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13388 bool
13389 EmulateInstructionARM::UnalignedSupport()
13390 {
13391     return (ArchVersion() >= ARMv7);
13392 }
13393 
13394 // The main addition and subtraction instructions can produce status information
13395 // about both unsigned carry and signed overflow conditions.  This status
13396 // information can be used to synthesize multi-word additions and subtractions.
13397 EmulateInstructionARM::AddWithCarryResult
13398 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13399 {
13400     uint32_t result;
13401     uint8_t carry_out;
13402     uint8_t overflow;
13403 
13404     uint64_t unsigned_sum = x + y + carry_in;
13405     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13406 
13407     result = UnsignedBits(unsigned_sum, 31, 0);
13408 //    carry_out = (result == unsigned_sum ? 0 : 1);
13409     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13410 
13411     if (carry_in)
13412         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13413     else
13414         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13415 
13416     AddWithCarryResult res = { result, carry_out, overflow };
13417     return res;
13418 }
13419 
13420 uint32_t
13421 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13422 {
13423     lldb::RegisterKind reg_kind;
13424     uint32_t reg_num;
13425     switch (num)
13426     {
13427     case SP_REG:
13428         reg_kind = eRegisterKindGeneric;
13429         reg_num  = LLDB_REGNUM_GENERIC_SP;
13430         break;
13431     case LR_REG:
13432         reg_kind = eRegisterKindGeneric;
13433         reg_num  = LLDB_REGNUM_GENERIC_RA;
13434         break;
13435     case PC_REG:
13436         reg_kind = eRegisterKindGeneric;
13437         reg_num  = LLDB_REGNUM_GENERIC_PC;
13438         break;
13439     default:
13440         if (num < SP_REG)
13441         {
13442             reg_kind = eRegisterKindDWARF;
13443             reg_num  = dwarf_r0 + num;
13444         }
13445         else
13446         {
13447             //assert(0 && "Invalid register number");
13448             *success = false;
13449             return UINT32_MAX;
13450         }
13451         break;
13452     }
13453 
13454     // Read our register.
13455     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13456 
13457     // When executing an ARM instruction , PC reads as the address of the current
13458     // instruction plus 8.
13459     // When executing a Thumb instruction , PC reads as the address of the current
13460     // instruction plus 4.
13461     if (num == 15)
13462     {
13463         if (CurrentInstrSet() == eModeARM)
13464             val += 8;
13465         else
13466             val += 4;
13467     }
13468 
13469     return val;
13470 }
13471 
13472 // Write the result to the ARM core register Rd, and optionally update the
13473 // condition flags based on the result.
13474 //
13475 // This helper method tries to encapsulate the following pseudocode from the
13476 // ARM Architecture Reference Manual:
13477 //
13478 // if d == 15 then         // Can only occur for encoding A1
13479 //     ALUWritePC(result); // setflags is always FALSE here
13480 // else
13481 //     R[d] = result;
13482 //     if setflags then
13483 //         APSR.N = result<31>;
13484 //         APSR.Z = IsZeroBit(result);
13485 //         APSR.C = carry;
13486 //         // APSR.V unchanged
13487 //
13488 // In the above case, the API client does not pass in the overflow arg, which
13489 // defaults to ~0u.
13490 bool
13491 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13492                                                   const uint32_t result,
13493                                                   const uint32_t Rd,
13494                                                   bool setflags,
13495                                                   const uint32_t carry,
13496                                                   const uint32_t overflow)
13497 {
13498     if (Rd == 15)
13499     {
13500         if (!ALUWritePC (context, result))
13501             return false;
13502     }
13503     else
13504     {
13505         lldb::RegisterKind reg_kind;
13506         uint32_t reg_num;
13507         switch (Rd)
13508         {
13509         case SP_REG:
13510             reg_kind = eRegisterKindGeneric;
13511             reg_num  = LLDB_REGNUM_GENERIC_SP;
13512             break;
13513         case LR_REG:
13514             reg_kind = eRegisterKindGeneric;
13515             reg_num  = LLDB_REGNUM_GENERIC_RA;
13516             break;
13517         default:
13518             reg_kind = eRegisterKindDWARF;
13519             reg_num  = dwarf_r0 + Rd;
13520         }
13521         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13522             return false;
13523         if (setflags)
13524             return WriteFlags (context, result, carry, overflow);
13525     }
13526     return true;
13527 }
13528 
13529 // This helper method tries to encapsulate the following pseudocode from the
13530 // ARM Architecture Reference Manual:
13531 //
13532 // APSR.N = result<31>;
13533 // APSR.Z = IsZeroBit(result);
13534 // APSR.C = carry;
13535 // APSR.V = overflow
13536 //
13537 // Default arguments can be specified for carry and overflow parameters, which means
13538 // not to update the respective flags.
13539 bool
13540 EmulateInstructionARM::WriteFlags (Context &context,
13541                                    const uint32_t result,
13542                                    const uint32_t carry,
13543                                    const uint32_t overflow)
13544 {
13545     m_new_inst_cpsr = m_opcode_cpsr;
13546     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13547     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13548     if (carry != ~0u)
13549         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13550     if (overflow != ~0u)
13551         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13552     if (m_new_inst_cpsr != m_opcode_cpsr)
13553     {
13554         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13555             return false;
13556     }
13557     return true;
13558 }
13559 
13560 bool
13561 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13562 {
13563     // Advance the ITSTATE bits to their values for the next instruction.
13564     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13565         m_it_session.ITAdvance();
13566 
13567     ARMOpcode *opcode_data = NULL;
13568 
13569     if (m_opcode_mode == eModeThumb)
13570         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13571     else if (m_opcode_mode == eModeARM)
13572         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13573 
13574     if (opcode_data == NULL)
13575         return false;
13576 
13577     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13578     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13579 
13580     bool success = false;
13581     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13582     {
13583         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13584                                                 dwarf_cpsr,
13585                                                 0,
13586                                                 &success);
13587     }
13588 
13589     // Only return false if we are unable to read the CPSR if we care about conditions
13590     if (success == false && m_ignore_conditions == false)
13591         return false;
13592 
13593     uint32_t orig_pc_value = 0;
13594     if (auto_advance_pc)
13595     {
13596         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13597         if (!success)
13598             return false;
13599     }
13600 
13601     // Call the Emulate... function.
13602     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13603     if (!success)
13604         return false;
13605 
13606     if (auto_advance_pc)
13607     {
13608         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13609         if (!success)
13610             return false;
13611 
13612         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13613         {
13614             if (opcode_data->size == eSize32)
13615                 after_pc_value += 4;
13616             else if (opcode_data->size == eSize16)
13617                 after_pc_value += 2;
13618 
13619             EmulateInstruction::Context context;
13620             context.type = eContextAdvancePC;
13621             context.SetNoArgs();
13622             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13623                 return false;
13624 
13625         }
13626     }
13627     return true;
13628 }
13629 
13630 bool
13631 EmulateInstructionARM::IsInstructionConditional()
13632 {
13633     const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
13634     return cond != 0xe && cond != 0xf && cond != UINT32_MAX;
13635 }
13636 
13637 bool
13638 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13639 {
13640     if (!test_data)
13641     {
13642         out_stream->Printf ("TestEmulation: Missing test data.\n");
13643         return false;
13644     }
13645 
13646     static ConstString opcode_key ("opcode");
13647     static ConstString before_key ("before_state");
13648     static ConstString after_key ("after_state");
13649 
13650     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13651 
13652     uint32_t test_opcode;
13653     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13654     {
13655         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13656         return false;
13657     }
13658     test_opcode = value_sp->GetUInt64Value ();
13659 
13660     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13661     {
13662         m_opcode_mode = eModeARM;
13663         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13664     }
13665     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13666     {
13667         m_opcode_mode = eModeThumb;
13668         if (test_opcode < 0x10000)
13669             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13670         else
13671             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13672 
13673     }
13674     else
13675     {
13676         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13677         return false;
13678     }
13679 
13680     EmulationStateARM before_state;
13681     EmulationStateARM after_state;
13682 
13683     value_sp = test_data->GetValueForKey (before_key);
13684     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13685     {
13686         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13687         return false;
13688     }
13689 
13690     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13691     if (!before_state.LoadStateFromDictionary (state_dictionary))
13692     {
13693         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13694         return false;
13695     }
13696 
13697     value_sp = test_data->GetValueForKey (after_key);
13698     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13699     {
13700         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13701         return false;
13702     }
13703 
13704     state_dictionary = value_sp->GetAsDictionary ();
13705     if (!after_state.LoadStateFromDictionary (state_dictionary))
13706     {
13707         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13708         return false;
13709     }
13710 
13711     SetBaton ((void *) &before_state);
13712     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13713                   &EmulationStateARM::WritePseudoMemory,
13714                   &EmulationStateARM::ReadPseudoRegister,
13715                   &EmulationStateARM::WritePseudoRegister);
13716 
13717     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13718     if (!success)
13719     {
13720         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13721         return false;
13722     }
13723 
13724     success = before_state.CompareState (after_state);
13725     if (!success)
13726         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13727 
13728     return success;
13729 }
13730 //
13731 //
13732 //const char *
13733 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13734 //{
13735 //    if (reg_kind == eRegisterKindGeneric)
13736 //    {
13737 //        switch (reg_num)
13738 //        {
13739 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13740 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13741 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13742 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13743 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13744 //        default: return NULL;
13745 //        }
13746 //    }
13747 //    else if (reg_kind == eRegisterKindDWARF)
13748 //    {
13749 //        return GetARMDWARFRegisterName (reg_num);
13750 //    }
13751 //    return NULL;
13752 //}
13753 //
13754 bool
13755 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13756 {
13757     unwind_plan.Clear();
13758     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13759 
13760     UnwindPlan::RowSP row(new UnwindPlan::Row);
13761 
13762     // Our previous Call Frame Address is the stack pointer
13763     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13764 
13765     unwind_plan.AppendRow (row);
13766     unwind_plan.SetSourceName ("EmulateInstructionARM");
13767     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13768     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13769     unwind_plan.SetReturnAddressRegister (dwarf_lr);
13770     return true;
13771 }
13772